Reland: Pass task runners to AudioManager constructor.

This patch replaces the internal AudioManagerBase::audio_thread with
an external task runner. The old implementation made it harder to test
and override the internal audio thread.

AudioManagerBase::Shutdown had to complete on the audio thread before
the AudioManager instance could be deleted. It relied on Thread::Stop
on the main thread to wait for the audio thread to shutdown. A subclass
using a different thread shared with other modules could not do that.

Passing a task runner into AudioManager and making GetTaskRunner
non-virtual ensures that the task runner will not change for the
lifetime of AudioManager instance.

BUG=594234
TBR=rkc,tommi,xhwang,jam,dalecurtis

Review URL: https://codereview.chromium.org/1894373002

Cr-Commit-Position: refs/heads/master@{#388211}
diff --git a/chromecast/media/audio/cast_audio_manager.cc b/chromecast/media/audio/cast_audio_manager.cc
index b098b56..e3b56d9 100644
--- a/chromecast/media/audio/cast_audio_manager.cc
+++ b/chromecast/media/audio/cast_audio_manager.cc
@@ -25,10 +25,15 @@
 namespace chromecast {
 namespace media {
 
-CastAudioManager::CastAudioManager(::media::AudioLogFactory* audio_log_factory,
-                                   MediaPipelineBackendManager* backend_manager)
-    : AudioManagerBase(audio_log_factory), backend_manager_(backend_manager) {
-}
+CastAudioManager::CastAudioManager(
+    scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+    scoped_refptr<base::SingleThreadTaskRunner> worker_task_runner,
+    ::media::AudioLogFactory* audio_log_factory,
+    MediaPipelineBackendManager* backend_manager)
+    : AudioManagerBase(std::move(task_runner),
+                       std::move(worker_task_runner),
+                       audio_log_factory),
+      backend_manager_(backend_manager) {}
 
 CastAudioManager::~CastAudioManager() {
   Shutdown();
diff --git a/chromecast/media/audio/cast_audio_manager.h b/chromecast/media/audio/cast_audio_manager.h
index 97e3e3cf..572b99fe 100644
--- a/chromecast/media/audio/cast_audio_manager.h
+++ b/chromecast/media/audio/cast_audio_manager.h
@@ -20,9 +20,11 @@
 
 class CastAudioManager : public ::media::AudioManagerBase {
  public:
-  CastAudioManager(::media::AudioLogFactory* audio_log_factory,
-                   MediaPipelineBackendManager* backend_manager);
-  ~CastAudioManager() override;
+  CastAudioManager(
+      scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+      scoped_refptr<base::SingleThreadTaskRunner> worker_task_runner,
+      ::media::AudioLogFactory* audio_log_factory,
+      MediaPipelineBackendManager* backend_manager);
 
   // AudioManager implementation.
   bool HasAudioOutputDevices() override;
@@ -38,6 +40,9 @@
   virtual std::unique_ptr<MediaPipelineBackend> CreateMediaPipelineBackend(
       const MediaPipelineDeviceParams& params);
 
+ protected:
+  ~CastAudioManager() override;
+
  private:
   // AudioManagerBase implementation.
   ::media::AudioOutputStream* MakeLinearOutputStream(
diff --git a/chromecast/media/audio/cast_audio_manager_factory.cc b/chromecast/media/audio/cast_audio_manager_factory.cc
index c932c4b..c6b7794 100644
--- a/chromecast/media/audio/cast_audio_manager_factory.cc
+++ b/chromecast/media/audio/cast_audio_manager_factory.cc
@@ -17,9 +17,15 @@
 
 CastAudioManagerFactory::~CastAudioManagerFactory() {}
 
-::media::AudioManager* CastAudioManagerFactory::CreateInstance(
+scoped_ptr<::media::AudioManager, ::media::AudioManagerDeleter>
+CastAudioManagerFactory::CreateInstance(
+    scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+    scoped_refptr<base::SingleThreadTaskRunner> worker_task_runner,
     ::media::AudioLogFactory* audio_log_factory) {
-  return new CastAudioManager(audio_log_factory, backend_manager_);
+  return scoped_ptr<::media::AudioManager, ::media::AudioManagerDeleter>(
+      new CastAudioManager(std::move(task_runner),
+                           std::move(worker_task_runner), audio_log_factory,
+                           backend_manager_));
 }
 
 }  // namespace media
diff --git a/chromecast/media/audio/cast_audio_manager_factory.h b/chromecast/media/audio/cast_audio_manager_factory.h
index 627a68d..d80cc84 100644
--- a/chromecast/media/audio/cast_audio_manager_factory.h
+++ b/chromecast/media/audio/cast_audio_manager_factory.h
@@ -20,8 +20,10 @@
   ~CastAudioManagerFactory() override;
 
   // ::media::AudioManagerFactory overrides.
-  ::media::AudioManager* CreateInstance(
-      ::media::AudioLogFactory* audio_log_factory) override;
+  scoped_ptr<::media::AudioManager, ::media::AudioManagerDeleter>
+  CreateInstance(scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+                 scoped_refptr<base::SingleThreadTaskRunner> worker_task_runner,
+                 ::media::AudioLogFactory* audio_log_factory) override;
 
  private:
   MediaPipelineBackendManager* const backend_manager_;
diff --git a/chromecast/media/audio/cast_audio_output_stream_unittest.cc b/chromecast/media/audio/cast_audio_output_stream_unittest.cc
index d529077..67bf295 100644
--- a/chromecast/media/audio/cast_audio_output_stream_unittest.cc
+++ b/chromecast/media/audio/cast_audio_output_stream_unittest.cc
@@ -10,7 +10,9 @@
 
 #include "base/bind.h"
 #include "base/macros.h"
+#include "base/run_loop.h"
 #include "base/synchronization/waitable_event.h"
+#include "base/thread_task_runner_handle.h"
 #include "chromecast/base/metrics/cast_metrics_test_helper.h"
 #include "chromecast/media/audio/cast_audio_manager.h"
 #include "chromecast/media/base/media_message_loop.h"
@@ -184,8 +186,9 @@
 
 class FakeAudioManager : public CastAudioManager {
  public:
-  FakeAudioManager()
-      : CastAudioManager(nullptr, nullptr), media_pipeline_backend_(nullptr) {}
+  FakeAudioManager(scoped_refptr<base::SingleThreadTaskRunner> task_runner)
+      : CastAudioManager(task_runner, task_runner, nullptr, nullptr),
+        media_pipeline_backend_(nullptr) {}
   ~FakeAudioManager() override {}
 
   // CastAudioManager overrides.
@@ -231,9 +234,9 @@
   void SetUp() override {
     metrics::InitializeMetricsHelperForTesting();
 
-    audio_manager_.reset(new FakeAudioManager);
-    audio_task_runner_ = audio_manager_->GetTaskRunner();
+    audio_task_runner_ = base::ThreadTaskRunnerHandle::Get();
     backend_task_runner_ = media::MediaMessageLoop::GetTaskRunner();
+    audio_manager_.reset(new FakeAudioManager(audio_task_runner_));
   }
 
   void TearDown() override {
@@ -256,107 +259,68 @@
 
   // Synchronous utility functions.
   ::media::AudioOutputStream* CreateStream() {
-    ::media::AudioOutputStream* stream = nullptr;
-
-    base::WaitableEvent completion_event(false, false);
-    audio_task_runner_->PostTask(
-        FROM_HERE,
-        base::Bind(&CastAudioOutputStreamTest::CreateStreamOnAudioThread,
-                   base::Unretained(this), GetAudioParams(), &stream,
-                   &completion_event));
-    completion_event.Wait();
-
-    return stream;
+    return audio_manager_->MakeAudioOutputStream(GetAudioParams(),
+                                                 kDefaultDeviceId);
   }
   bool OpenStream(::media::AudioOutputStream* stream) {
-    DCHECK(stream);
-
-    bool success = false;
-    base::WaitableEvent completion_event(false, false);
-    audio_task_runner_->PostTask(
-        FROM_HERE,
-        base::Bind(&CastAudioOutputStreamTest::OpenStreamOnAudioThread,
-                   base::Unretained(this), stream, &success,
-                   &completion_event));
-    completion_event.Wait();
-
+    bool success = stream->Open();
     // Drain the backend task runner so that appropriate states are set on
     // the backend pipeline devices.
     RunUntilIdle(backend_task_runner_.get());
     return success;
   }
   void CloseStream(::media::AudioOutputStream* stream) {
-    audio_task_runner_->PostTask(FROM_HERE,
-                                 base::Bind(&::media::AudioOutputStream::Close,
-                                            base::Unretained(stream)));
-    RunUntilIdle(audio_task_runner_.get());
+    stream->Close();
     RunUntilIdle(backend_task_runner_.get());
     // Backend task runner may have posted more tasks to the audio task runner.
     // So we need to drain it once more.
-    RunUntilIdle(audio_task_runner_.get());
+    message_loop_.RunUntilIdle();
   }
   void StartStream(
       ::media::AudioOutputStream* stream,
       ::media::AudioOutputStream::AudioSourceCallback* source_callback) {
-    audio_task_runner_->PostTask(
-        FROM_HERE, base::Bind(&::media::AudioOutputStream::Start,
-                              base::Unretained(stream), source_callback));
-    // Drain the audio task runner twice so that tasks posted by
+    stream->Start(source_callback);
+    // Drain the audio task runner so that tasks posted by
     // media::AudioOutputStream::Start are run as well.
-    RunUntilIdle(audio_task_runner_.get());
-    RunUntilIdle(audio_task_runner_.get());
+    message_loop_.RunUntilIdle();
     // Drain the backend task runner so that appropriate states are set on
     // the backend pipeline devices.
     RunUntilIdle(backend_task_runner_.get());
     // Drain the audio task runner again to run the tasks posted by the
     // backend on audio task runner.
-    RunUntilIdle(audio_task_runner_.get());
+    message_loop_.RunUntilIdle();
   }
   void StopStream(::media::AudioOutputStream* stream) {
-    audio_task_runner_->PostTask(FROM_HERE,
-                                 base::Bind(&::media::AudioOutputStream::Stop,
-                                            base::Unretained(stream)));
-    RunUntilIdle(audio_task_runner_.get());
+    stream->Stop();
     // Drain the backend task runner so that appropriate states are set on
     // the backend pipeline devices.
     RunUntilIdle(backend_task_runner_.get());
   }
   void SetStreamVolume(::media::AudioOutputStream* stream, double volume) {
-    audio_task_runner_->PostTask(
-        FROM_HERE, base::Bind(&::media::AudioOutputStream::SetVolume,
-                              base::Unretained(stream), volume));
-    RunUntilIdle(audio_task_runner_.get());
+    stream->SetVolume(volume);
     // Drain the backend task runner so that appropriate states are set on
     // the backend pipeline devices.
     RunUntilIdle(backend_task_runner_.get());
   }
   double GetStreamVolume(::media::AudioOutputStream* stream) {
     double volume = 0.0;
-    audio_task_runner_->PostTask(
-        FROM_HERE, base::Bind(&::media::AudioOutputStream::GetVolume,
-                              base::Unretained(stream), &volume));
-    RunUntilIdle(audio_task_runner_.get());
+    stream->GetVolume(&volume);
     // No need to drain the backend task runner because getting the volume
     // does not involve posting any task to the backend.
     return volume;
   }
 
-  void CreateStreamOnAudioThread(const ::media::AudioParameters& audio_params,
-                                 ::media::AudioOutputStream** stream,
-                                 base::WaitableEvent* completion_event) {
-    DCHECK(audio_task_runner_->BelongsToCurrentThread());
-    *stream = audio_manager_->MakeAudioOutputStream(GetAudioParams(),
-                                                    kDefaultDeviceId);
-    completion_event->Signal();
-  }
-  void OpenStreamOnAudioThread(::media::AudioOutputStream* stream,
-                               bool* success,
-                               base::WaitableEvent* completion_event) {
-    DCHECK(audio_task_runner_->BelongsToCurrentThread());
-    *success = stream->Open();
-    completion_event->Signal();
+  void RunAudioLoopFor(int frames) {
+    ::media::AudioParameters audio_params = GetAudioParams();
+    base::TimeDelta duration = audio_params.GetBufferDuration() * frames;
+
+    base::RunLoop run_loop;
+    message_loop_.task_runner()->PostDelayedTask(
+        FROM_HERE, run_loop.QuitClosure(), duration);
+    run_loop.Run();
   }
 
+  base::MessageLoop message_loop_;
   std::unique_ptr<FakeAudioManager> audio_manager_;
   scoped_refptr<base::SingleThreadTaskRunner> audio_task_runner_;
   scoped_refptr<base::SingleThreadTaskRunner> backend_task_runner_;
@@ -476,6 +440,7 @@
   std::unique_ptr<FakeAudioSourceCallback> source_callback(
       new FakeAudioSourceCallback);
   StartStream(stream, source_callback.get());
+  RunAudioLoopFor(2);
   StopStream(stream);
 
   // Verify that the stream pushed frames to the backend.
@@ -518,10 +483,7 @@
 
   // Sleep for a few frames and verify that more frames were not pushed
   // because the backend device was busy.
-  ::media::AudioParameters audio_params = GetAudioParams();
-  base::TimeDelta pause = audio_params.GetBufferDuration() * 5;
-  base::PlatformThread::Sleep(pause);
-  RunUntilIdle(audio_task_runner_.get());
+  RunAudioLoopFor(5);
   RunUntilIdle(backend_task_runner_.get());
   EXPECT_EQ(1u, audio_decoder->pushed_buffer_count());
 
@@ -532,9 +494,7 @@
       base::Bind(&FakeAudioDecoder::set_pipeline_status,
                  base::Unretained(audio_decoder),
                  FakeAudioDecoder::PIPELINE_STATUS_OK));
-
-  base::PlatformThread::Sleep(pause);
-  RunUntilIdle(audio_task_runner_.get());
+  RunAudioLoopFor(5);
   RunUntilIdle(backend_task_runner_.get());
   EXPECT_LT(1u, audio_decoder->pushed_buffer_count());
   EXPECT_FALSE(source_callback->error());
@@ -555,6 +515,7 @@
   std::unique_ptr<FakeAudioSourceCallback> source_callback(
       new FakeAudioSourceCallback);
   StartStream(stream, source_callback.get());
+  RunAudioLoopFor(2);
 
   // Make sure that AudioOutputStream attempted to push the initial frame.
   EXPECT_LT(0u, audio_decoder->pushed_buffer_count());
@@ -578,6 +539,7 @@
   std::unique_ptr<FakeAudioSourceCallback> source_callback(
       new FakeAudioSourceCallback);
   StartStream(stream, source_callback.get());
+  RunAudioLoopFor(5);
 
   // Make sure that one frame was pushed.
   EXPECT_EQ(1u, audio_decoder->pushed_buffer_count());
@@ -590,7 +552,7 @@
                  base::Unretained(audio_decoder),
                  FakeAudioDecoder::PIPELINE_STATUS_OK));
 
-  RunUntilIdle(audio_task_runner_.get());
+  RunAudioLoopFor(5);
   RunUntilIdle(backend_task_runner_.get());
   // AudioOutputStream must report error to source callback.
   EXPECT_TRUE(source_callback->error());
@@ -625,16 +587,11 @@
 
   std::unique_ptr<FakeAudioSourceCallback> source_callback(
       new FakeAudioSourceCallback);
-  audio_task_runner_->PostTask(
-      FROM_HERE, base::Bind(&::media::AudioOutputStream::Start,
-                            base::Unretained(stream), source_callback.get()));
-  audio_task_runner_->PostTask(
-      FROM_HERE,
-      base::Bind(&::media::AudioOutputStream::Stop, base::Unretained(stream)));
-  audio_task_runner_->PostTask(
-      FROM_HERE, base::Bind(&::media::AudioOutputStream::Start,
-                            base::Unretained(stream), source_callback.get()));
-  RunUntilIdle(audio_task_runner_.get());
+  stream->Start(source_callback.get());
+  RunAudioLoopFor(2);
+  stream->Stop();
+  stream->Start(source_callback.get());
+  RunAudioLoopFor(2);
   RunUntilIdle(backend_task_runner_.get());
 
   FakeAudioDecoder* audio_device = GetAudio();
diff --git a/components/audio_modem/BUILD.gn b/components/audio_modem/BUILD.gn
index d14a7b3..83cd882 100644
--- a/components/audio_modem/BUILD.gn
+++ b/components/audio_modem/BUILD.gn
@@ -63,6 +63,7 @@
   deps = [
     ":test_support",
     "//base",
+    "//base/test:test_support",
     "//content/test:test_support",
     "//media",
     "//media:shared_memory_support",
diff --git a/components/audio_modem/audio_player_impl.cc b/components/audio_modem/audio_player_impl.cc
index cd52f05..2a02f5a 100644
--- a/components/audio_modem/audio_player_impl.cc
+++ b/components/audio_modem/audio_player_impl.cc
@@ -8,11 +8,9 @@
 #include <string>
 
 #include "base/bind.h"
-#include "base/bind_helpers.h"
+#include "base/location.h"
 #include "base/logging.h"
-#include "base/run_loop.h"
 #include "components/audio_modem/public/audio_modem_types.h"
-#include "content/public/browser/browser_thread.h"
 #include "media/audio/audio_manager.h"
 #include "media/audio/audio_parameters.h"
 #include "media/base/audio_bus.h"
@@ -162,19 +160,4 @@
                  base::Unretained(this)));
 }
 
-void AudioPlayerImpl::FlushAudioLoopForTesting() {
-  if (media::AudioManager::Get()->GetTaskRunner()->BelongsToCurrentThread())
-    return;
-
-  // Queue task on the audio thread, when it is executed, that means we've
-  // successfully executed all the tasks before us.
-  base::RunLoop rl;
-  media::AudioManager::Get()->GetTaskRunner()->PostTaskAndReply(
-      FROM_HERE,
-      base::Bind(base::IgnoreResult(&AudioPlayerImpl::FlushAudioLoopForTesting),
-                 base::Unretained(this)),
-      rl.QuitClosure());
-  rl.Run();
-}
-
 }  // namespace audio_modem
diff --git a/components/audio_modem/audio_player_impl.h b/components/audio_modem/audio_player_impl.h
index 7ea518b..50f10bf 100644
--- a/components/audio_modem/audio_player_impl.h
+++ b/components/audio_modem/audio_player_impl.h
@@ -65,10 +65,6 @@
                  uint32_t frames_skipped) override;
   void OnError(media::AudioOutputStream* stream) override;
 
-  // Flushes the audio loop, making sure that any queued operations are
-  // performed.
-  void FlushAudioLoopForTesting();
-
   bool is_playing_;
 
   // Self-deleting object.
diff --git a/components/audio_modem/audio_player_unittest.cc b/components/audio_modem/audio_player_unittest.cc
index 153e6c0..2a96c0f9 100644
--- a/components/audio_modem/audio_player_unittest.cc
+++ b/components/audio_modem/audio_player_unittest.cc
@@ -8,11 +8,12 @@
 #include "base/location.h"
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
-#include "base/single_thread_task_runner.h"
+#include "base/run_loop.h"
+#include "base/test/test_message_loop.h"
+#include "base/thread_task_runner_handle.h"
 #include "components/audio_modem/audio_player_impl.h"
 #include "components/audio_modem/public/audio_modem_types.h"
 #include "components/audio_modem/test/random_samples.h"
-#include "media/audio/audio_manager.h"
 #include "media/audio/audio_manager_base.h"
 #include "media/base/audio_bus.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -77,8 +78,9 @@
                         public base::SupportsWeakPtr<AudioPlayerTest> {
  public:
   AudioPlayerTest() : buffer_index_(0), player_(nullptr) {
-    if (!media::AudioManager::Get())
-      media::AudioManager::CreateForTesting();
+    audio_manager_ = media::AudioManager::CreateForTesting(
+        base::ThreadTaskRunnerHandle::Get());
+    base::RunLoop().RunUntilIdle();
   }
 
   ~AudioPlayerTest() override { DeletePlayer(); }
@@ -91,6 +93,7 @@
         kMaxFrameCount,
         base::Bind(&AudioPlayerTest::GatherSamples, AsWeakPtr())));
     player_->Initialize();
+    base::RunLoop().RunUntilIdle();
   }
 
   void DeletePlayer() {
@@ -98,6 +101,7 @@
       return;
     player_->Finalize();
     player_ = nullptr;
+    base::RunLoop().RunUntilIdle();
   }
 
   void PlayAndVerifySamples(
@@ -107,8 +111,8 @@
     buffer_ = media::AudioBus::Create(1, kMaxFrameCount);
     buffer_index_ = 0;
     player_->Play(samples);
-    player_->FlushAudioLoopForTesting();
     player_->Stop();
+    base::RunLoop().RunUntilIdle();
 
     int differences = 0;
     for (int i = 0; i < kMaxFrameCount; ++i) {
@@ -129,19 +133,20 @@
 
  protected:
   bool IsPlaying() {
-    player_->FlushAudioLoopForTesting();
+    base::RunLoop().RunUntilIdle();
     return player_->is_playing_;
   }
 
   static const int kDefaultFrameCount = 1024;
   static const int kMaxFrameCount = 1024 * 100;
 
+  base::TestMessageLoop message_loop_;
+  media::ScopedAudioManagerPtr audio_manager_;
   scoped_ptr<media::AudioBus> buffer_;
   int buffer_index_;
 
   // Deleted by calling Finalize() on the object.
   AudioPlayerImpl* player_;
-  base::MessageLoop message_loop_;
 };
 
 TEST_F(AudioPlayerTest, BasicPlayAndStop) {
@@ -151,16 +156,19 @@
 
   player_->Play(samples);
   EXPECT_TRUE(IsPlaying());
+
   player_->Stop();
   EXPECT_FALSE(IsPlaying());
-  player_->Play(samples);
 
+  player_->Play(samples);
   EXPECT_TRUE(IsPlaying());
+
   player_->Stop();
   EXPECT_FALSE(IsPlaying());
-  player_->Play(samples);
 
+  player_->Play(samples);
   EXPECT_TRUE(IsPlaying());
+
   player_->Stop();
   EXPECT_FALSE(IsPlaying());
 
diff --git a/components/audio_modem/audio_recorder_impl.cc b/components/audio_modem/audio_recorder_impl.cc
index 8d1b2c5..06bc728 100644
--- a/components/audio_modem/audio_recorder_impl.cc
+++ b/components/audio_modem/audio_recorder_impl.cc
@@ -198,20 +198,4 @@
                  base::Unretained(this)));
 }
 
-void AudioRecorderImpl::FlushAudioLoopForTesting() {
-  if (media::AudioManager::Get()->GetTaskRunner()->BelongsToCurrentThread())
-    return;
-
-  // Queue task on the audio thread, when it is executed, that means we've
-  // successfully executed all the tasks before us.
-  base::RunLoop rl;
-  media::AudioManager::Get()->GetTaskRunner()->PostTaskAndReply(
-      FROM_HERE,
-      base::Bind(
-          base::IgnoreResult(&AudioRecorderImpl::FlushAudioLoopForTesting),
-          base::Unretained(this)),
-      rl.QuitClosure());
-  rl.Run();
-}
-
 }  // namespace audio_modem
diff --git a/components/audio_modem/audio_recorder_impl.h b/components/audio_modem/audio_recorder_impl.h
index cce75fb..b0f5486 100644
--- a/components/audio_modem/audio_recorder_impl.h
+++ b/components/audio_modem/audio_recorder_impl.h
@@ -79,10 +79,6 @@
               double volume) override;
   void OnError(media::AudioInputStream* stream) override;
 
-  // Flushes the audio loop, making sure that any queued operations are
-  // performed.
-  void FlushAudioLoopForTesting();
-
   bool is_recording_;
 
   media::AudioInputStream* stream_;
diff --git a/components/audio_modem/audio_recorder_unittest.cc b/components/audio_modem/audio_recorder_unittest.cc
index e960cd389..08b9a52 100644
--- a/components/audio_modem/audio_recorder_unittest.cc
+++ b/components/audio_modem/audio_recorder_unittest.cc
@@ -12,6 +12,7 @@
 #include "base/macros.h"
 #include "base/memory/aligned_memory.h"
 #include "base/run_loop.h"
+#include "base/thread_task_runner_handle.h"
 #include "build/build_config.h"
 #include "components/audio_modem/audio_recorder_impl.h"
 #include "components/audio_modem/public/audio_modem_types.h"
@@ -82,8 +83,9 @@
 class AudioRecorderTest : public testing::Test {
  public:
   AudioRecorderTest() : total_samples_(0), recorder_(nullptr) {
-    if (!media::AudioManager::Get())
-      media::AudioManager::CreateForTesting();
+    audio_manager_ = media::AudioManager::CreateForTesting(
+        base::ThreadTaskRunnerHandle::Get());
+    base::RunLoop().RunUntilIdle();
   }
 
   ~AudioRecorderTest() override {
@@ -101,6 +103,7 @@
       recorder_ = new AudioRecorderImpl();
       recorder_->Initialize(base::Bind(&AudioRecorderTest::DecodeSamples,
                                        base::Unretained(this)));
+      base::RunLoop().RunUntilIdle();
     } else {
       CreateRecorder(kSomeNumber);
     }
@@ -124,6 +127,7 @@
     recorder_->set_params_for_testing(new media::AudioParameters(params_));
     recorder_->Initialize(
         base::Bind(&AudioRecorderTest::DecodeSamples, base::Unretained(this)));
+    base::RunLoop().RunUntilIdle();
   }
 
   void DeleteRecorder() {
@@ -131,6 +135,7 @@
       return;
     recorder_->Finalize();
     recorder_ = nullptr;
+    base::RunLoop().RunUntilIdle();
   }
 
   void RecordAndVerifySamples() {
@@ -183,10 +188,13 @@
     return samples;
   }
   bool IsRecording() {
-    recorder_->FlushAudioLoopForTesting();
+    base::RunLoop().RunUntilIdle();
     return recorder_->is_recording_;
   }
 
+  content::TestBrowserThreadBundle thread_bundle_;
+  media::ScopedAudioManagerPtr audio_manager_;
+
   std::vector<float*> channel_data_;
   media::AudioParameters params_;
   size_t total_samples_;
@@ -197,7 +205,6 @@
   std::string received_samples_;
 
   scoped_ptr<base::RunLoop> run_loop_;
-  content::TestBrowserThreadBundle thread_bundle_;
 };
 
 
@@ -213,16 +220,19 @@
 
   recorder_->Record();
   EXPECT_TRUE(IsRecording());
+
   recorder_->Stop();
   EXPECT_FALSE(IsRecording());
-  recorder_->Record();
 
+  recorder_->Record();
   EXPECT_TRUE(IsRecording());
+
   recorder_->Stop();
   EXPECT_FALSE(IsRecording());
-  recorder_->Record();
 
+  recorder_->Record();
   EXPECT_TRUE(IsRecording());
+
   recorder_->Stop();
   EXPECT_FALSE(IsRecording());
 
diff --git a/content/browser/browser_main_loop.cc b/content/browser/browser_main_loop.cc
index e96d2f92..bb67429 100644
--- a/content/browser/browser_main_loop.cc
+++ b/content/browser/browser_main_loop.cc
@@ -75,7 +75,6 @@
 #include "content/public/common/result_codes.h"
 #include "device/battery/battery_status_service.h"
 #include "ipc/mojo/scoped_ipc_support.h"
-#include "media/audio/audio_manager.h"
 #include "media/base/media.h"
 #include "media/base/user_input_monitor.h"
 #include "media/midi/midi_manager.h"
@@ -1226,8 +1225,7 @@
 
   {
     TRACE_EVENT0("startup", "BrowserThreadsStarted::Subsystem:AudioMan");
-    audio_manager_.reset(media::AudioManager::CreateWithHangTimer(
-        MediaInternals::GetInstance(), io_thread_->task_runner()));
+    CreateAudioManager();
   }
 
   {
@@ -1455,4 +1453,34 @@
           base::Bind(OnStoppedStartupTracing, startup_trace_file_)));
 }
 
+void BrowserMainLoop::CreateAudioManager() {
+  DCHECK(!audio_thread_);
+  DCHECK(!audio_manager_);
+  // TODO(alokp): Allow content embedders to override the default
+  // task runners by defining ContentBrowserClient::GetAudioTaskRunner.
+  scoped_refptr<base::SingleThreadTaskRunner> audio_task_runner;
+  scoped_refptr<base::SingleThreadTaskRunner> worker_task_runner;
+  scoped_refptr<base::SingleThreadTaskRunner> monitor_task_runner;
+  audio_thread_.reset(new base::Thread("AudioThread"));
+#if defined(OS_WIN)
+  audio_thread_->init_com_with_mta(true);
+#endif  // defined(OS_WIN)
+  CHECK(audio_thread_->Start());
+#if defined(OS_MACOSX)
+  // On Mac audio task runner must belong to the main thread.
+  // See http://crbug.com/158170.
+  // Since the audio thread is the UI thread, a hang monitor is not
+  // necessary or recommended.
+  audio_task_runner = base::ThreadTaskRunnerHandle::Get();
+  worker_task_runner = audio_thread_->task_runner();
+#else
+  audio_task_runner = audio_thread_->task_runner();
+  worker_task_runner = audio_thread_->task_runner();
+  monitor_task_runner = io_thread_->task_runner();
+#endif  // defined(OS_MACOSX)
+  audio_manager_ = media::AudioManager::Create(
+      std::move(audio_task_runner), std::move(worker_task_runner),
+      std::move(monitor_task_runner), MediaInternals::GetInstance());
+}
+
 }  // namespace content
diff --git a/content/browser/browser_main_loop.h b/content/browser/browser_main_loop.h
index 7052211..4d344458 100644
--- a/content/browser/browser_main_loop.h
+++ b/content/browser/browser_main_loop.h
@@ -14,6 +14,7 @@
 #include "build/build_config.h"
 #include "content/browser/browser_process_sub_thread.h"
 #include "content/public/browser/browser_main_runner.h"
+#include "media/audio/audio_manager.h"
 
 #if defined(USE_AURA)
 namespace aura {
@@ -39,7 +40,6 @@
 }
 
 namespace media {
-class AudioManager;
 #if defined(OS_WIN)
 class SystemMessageWindowWin;
 #elif defined(OS_LINUX) && defined(USE_UDEV)
@@ -169,6 +169,7 @@
   void InitStartupTracingForDuration(const base::CommandLine& command_line);
   void EndStartupTracing();
 
+  void CreateAudioManager();
   bool UsingInProcessGpu() const;
 
   // Quick reference for initialization order:
@@ -260,7 +261,9 @@
 
   // |user_input_monitor_| has to outlive |audio_manager_|, so declared first.
   std::unique_ptr<media::UserInputMonitor> user_input_monitor_;
-  std::unique_ptr<media::AudioManager> audio_manager_;
+  // AudioThread needs to outlive |audio_manager_|.
+  std::unique_ptr<base::Thread> audio_thread_;
+  media::ScopedAudioManagerPtr audio_manager_;
 
   std::unique_ptr<media::midi::MidiManager> midi_manager_;
 
diff --git a/content/browser/renderer_host/media/audio_input_device_manager_unittest.cc b/content/browser/renderer_host/media/audio_input_device_manager_unittest.cc
index dd387bb..a465a63 100644
--- a/content/browser/renderer_host/media/audio_input_device_manager_unittest.cc
+++ b/content/browser/renderer_host/media/audio_input_device_manager_unittest.cc
@@ -13,11 +13,12 @@
 #include "base/location.h"
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
+#include "base/run_loop.h"
 #include "base/single_thread_task_runner.h"
-#include "base/synchronization/waitable_event.h"
+#include "base/thread_task_runner_handle.h"
 #include "build/build_config.h"
-#include "content/browser/browser_thread_impl.h"
 #include "content/public/common/media_stream_request.h"
+#include "content/public/test/test_browser_thread_bundle.h"
 #include "media/audio/audio_manager_base.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -62,22 +63,16 @@
 
  protected:
   void SetUp() override {
-    // The test must run on Browser::IO.
-    message_loop_.reset(new base::MessageLoopForIO);
-    io_thread_.reset(new BrowserThreadImpl(BrowserThread::IO,
-                                           message_loop_.get()));
-    audio_manager_.reset(media::AudioManager::CreateForTesting());
-    // Wait for audio thread initialization to complete.  Otherwise the
-    // enumeration type may not have been set yet.
-    base::WaitableEvent event(false, false);
-    audio_manager_->GetTaskRunner()->PostTask(FROM_HERE, base::Bind(
-        &base::WaitableEvent::Signal, base::Unretained(&event)));
-    event.Wait();
+    audio_manager_ = media::AudioManager::CreateForTesting(
+        base::ThreadTaskRunnerHandle::Get());
+    // Flush the message loop to ensure proper initialization of AudioManager.
+    base::RunLoop().RunUntilIdle();
+
     manager_ = new AudioInputDeviceManager(audio_manager_.get());
     manager_->UseFakeDevice();
     audio_input_listener_.reset(new MockAudioInputDeviceManagerListener());
     manager_->Register(audio_input_listener_.get(),
-                       message_loop_->task_runner().get());
+                       audio_manager_->GetTaskRunner());
 
     // Gets the enumerated device list from the AudioInputDeviceManager.
     manager_->EnumerateDevices(MEDIA_DEVICE_AUDIO_CAPTURE);
@@ -87,19 +82,17 @@
         .WillOnce(SaveArg<1>(&devices_));
 
     // Wait until we get the list.
-    message_loop_->RunUntilIdle();
+    base::RunLoop().RunUntilIdle();
   }
 
   void TearDown() override {
     manager_->Unregister();
-    io_thread_.reset();
   }
 
-  std::unique_ptr<base::MessageLoop> message_loop_;
-  std::unique_ptr<BrowserThreadImpl> io_thread_;
+  TestBrowserThreadBundle thread_bundle_;
   scoped_refptr<AudioInputDeviceManager> manager_;
   std::unique_ptr<MockAudioInputDeviceManagerListener> audio_input_listener_;
-  std::unique_ptr<media::AudioManager> audio_manager_;
+  media::ScopedAudioManagerPtr audio_manager_;
   StreamDeviceInfoArray devices_;
 
  private:
@@ -123,7 +116,7 @@
                 Opened(MEDIA_DEVICE_AUDIO_CAPTURE, session_id))
         .Times(1);
     // Waits for the callback.
-    message_loop_->RunUntilIdle();
+    base::RunLoop().RunUntilIdle();
 
     manager_->Close(session_id);
     EXPECT_CALL(*audio_input_listener_,
@@ -131,7 +124,7 @@
         .Times(1);
 
     // Waits for the callback.
-    message_loop_->RunUntilIdle();
+    base::RunLoop().RunUntilIdle();
   }
 }
 
@@ -156,7 +149,7 @@
         .Times(1);
 
     // Waits for the callback.
-    message_loop_->RunUntilIdle();
+    base::RunLoop().RunUntilIdle();
   }
 
   // Checks if the session_ids are unique.
@@ -174,7 +167,7 @@
         .Times(1);
 
     // Waits for the callback.
-    message_loop_->RunUntilIdle();
+    base::RunLoop().RunUntilIdle();
   }
 }
 
@@ -196,7 +189,7 @@
       .Times(1);
 
   // Waits for the callback.
-  message_loop_->RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
 }
 
 // Opens default device twice.
@@ -218,7 +211,7 @@
               Opened(MEDIA_DEVICE_AUDIO_CAPTURE, second_session_id))
       .Times(1);
   // Waits for the callback.
-  message_loop_->RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
 
   manager_->Close(first_session_id);
   manager_->Close(second_session_id);
@@ -229,7 +222,7 @@
               Closed(MEDIA_DEVICE_AUDIO_CAPTURE, second_session_id))
       .Times(1);
   // Waits for the callback.
-  message_loop_->RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
 }
 
 // Accesses then closes the sessions after opening the devices.
@@ -251,7 +244,7 @@
     EXPECT_CALL(*audio_input_listener_,
                 Opened(MEDIA_DEVICE_AUDIO_CAPTURE, session_id[index]))
         .Times(1);
-    message_loop_->RunUntilIdle();
+    base::RunLoop().RunUntilIdle();
 
     const StreamDeviceInfo* info = manager_->GetOpenedDeviceInfoById(
         session_id[index]);
@@ -261,7 +254,7 @@
     EXPECT_CALL(*audio_input_listener_,
                 Closed(MEDIA_DEVICE_AUDIO_CAPTURE, session_id[index]))
         .Times(1);
-    message_loop_->RunUntilIdle();
+    base::RunLoop().RunUntilIdle();
   }
 }
 
@@ -275,7 +268,7 @@
   EXPECT_CALL(*audio_input_listener_,
               Opened(MEDIA_DEVICE_AUDIO_CAPTURE, session_id))
       .Times(1);
-  message_loop_->RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
 
   // Access a non-opened device.
   // This should fail and return an empty StreamDeviceInfo.
@@ -288,7 +281,7 @@
   EXPECT_CALL(*audio_input_listener_,
               Closed(MEDIA_DEVICE_AUDIO_CAPTURE, session_id))
       .Times(1);
-  message_loop_->RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
 }
 
 }  // namespace content
diff --git a/content/browser/renderer_host/media/audio_output_device_enumerator.cc b/content/browser/renderer_host/media/audio_output_device_enumerator.cc
index 24ef8f9e..9c469c60 100644
--- a/content/browser/renderer_host/media/audio_output_device_enumerator.cc
+++ b/content/browser/renderer_host/media/audio_output_device_enumerator.cc
@@ -117,7 +117,7 @@
   is_enumeration_ongoing_ = true;
   seq_last_enumeration_ = NewEventSequence();
   base::PostTaskAndReplyWithResult(
-      audio_manager_->GetTaskRunner().get(), FROM_HERE,
+      audio_manager_->GetTaskRunner(), FROM_HERE,
       base::Bind(&EnumerateDevicesOnDeviceThread, audio_manager_),
       base::Bind(&AudioOutputDeviceEnumerator::DevicesEnumerated,
                  weak_factory_.GetWeakPtr()));
diff --git a/content/browser/renderer_host/media/audio_output_device_enumerator_unittest.cc b/content/browser/renderer_host/media/audio_output_device_enumerator_unittest.cc
index f84f87e..c84a684 100644
--- a/content/browser/renderer_host/media/audio_output_device_enumerator_unittest.cc
+++ b/content/browser/renderer_host/media/audio_output_device_enumerator_unittest.cc
@@ -12,7 +12,6 @@
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
 #include "base/run_loop.h"
-#include "base/single_thread_task_runner.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/thread_task_runner_handle.h"
 #include "content/public/test/test_browser_thread_bundle.h"
@@ -31,7 +30,10 @@
 class MockAudioManager : public media::FakeAudioManager {
  public:
   MockAudioManager(size_t num_devices)
-      : FakeAudioManager(&fake_audio_log_factory_), num_devices_(num_devices) {}
+      : FakeAudioManager(base::ThreadTaskRunnerHandle::Get(),
+                         base::ThreadTaskRunnerHandle::Get(),
+                         &fake_audio_log_factory_),
+        num_devices_(num_devices) {}
   MockAudioManager() : MockAudioManager(0) {}
   ~MockAudioManager() override {}
 
@@ -81,9 +83,7 @@
 
 class AudioOutputDeviceEnumeratorTest : public ::testing::Test {
  public:
-  AudioOutputDeviceEnumeratorTest()
-      : thread_bundle_(), task_runner_(base::ThreadTaskRunnerHandle::Get()) {}
-
+  AudioOutputDeviceEnumeratorTest() {}
   ~AudioOutputDeviceEnumeratorTest() override {}
 
   MOCK_METHOD1(MockCallback, void(const AudioOutputDeviceEnumeration&));
@@ -110,18 +110,19 @@
                               const AudioOutputDeviceEnumeration& result) {
     EXPECT_EQ(actual_devices_expected, result.has_actual_devices);
     EXPECT_EQ(num_entries_expected, result.devices.size());
-    task_runner_->PostTask(FROM_HERE, run_loop_.QuitClosure());
+    base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
+                                                  run_loop_.QuitClosure());
   }
 
   void QuitCallback(const AudioOutputDeviceEnumeration& result) {
     MockCallback(result);
-    task_runner_->PostTask(FROM_HERE, run_loop_.QuitClosure());
+    base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
+                                                  run_loop_.QuitClosure());
   }
 
  protected:
-  std::unique_ptr<MockAudioManager> audio_manager_;
   TestBrowserThreadBundle thread_bundle_;
-  scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
+  std::unique_ptr<MockAudioManager, media::AudioManagerDeleter> audio_manager_;
   base::RunLoop run_loop_;
 
  private:
diff --git a/content/browser/renderer_host/media/audio_renderer_host.cc b/content/browser/renderer_host/media/audio_renderer_host.cc
index ae58022..1d72170 100644
--- a/content/browser/renderer_host/media/audio_renderer_host.cc
+++ b/content/browser/renderer_host/media/audio_renderer_host.cc
@@ -484,7 +484,7 @@
       !media_stream_manager_->audio_output_device_enumerator()
            ->IsCacheEnabled()) {
     base::PostTaskAndReplyWithResult(
-        audio_manager_->GetTaskRunner().get(), FROM_HERE,
+        audio_manager_->GetTaskRunner(), FROM_HERE,
         base::Bind(&GetDefaultDeviceInfoOnDeviceThread, audio_manager_),
         base::Bind(&AudioRendererHost::OnDeviceIDTranslated, this, stream_id,
                    true));
diff --git a/content/browser/renderer_host/media/audio_renderer_host_unittest.cc b/content/browser/renderer_host/media/audio_renderer_host_unittest.cc
index a0cdfdb4..467e2be 100644
--- a/content/browser/renderer_host/media/audio_renderer_host_unittest.cc
+++ b/content/browser/renderer_host/media/audio_renderer_host_unittest.cc
@@ -187,7 +187,8 @@
 class AudioRendererHostTest : public testing::Test {
  public:
   AudioRendererHostTest() {
-    audio_manager_.reset(media::AudioManager::CreateForTesting());
+    audio_manager_ = media::AudioManager::CreateForTesting(
+        base::ThreadTaskRunnerHandle::Get());
     base::CommandLine::ForCurrentProcess()->AppendSwitch(
         switches::kUseFakeDeviceForMediaStream);
     media_stream_manager_.reset(new MediaStreamManager(audio_manager_.get()));
@@ -328,7 +329,7 @@
   // TestBrowserThreadBundle.
   std::unique_ptr<MediaStreamManager> media_stream_manager_;
   TestBrowserThreadBundle thread_bundle_;
-  std::unique_ptr<media::AudioManager> audio_manager_;
+  media::ScopedAudioManagerPtr audio_manager_;
   MockAudioMirroringManager mirroring_manager_;
   scoped_refptr<MockAudioRendererHost> host_;
 
diff --git a/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc b/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc
index 0c18286..5560d0e 100644
--- a/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc
+++ b/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc
@@ -225,8 +225,8 @@
 class MediaStreamDispatcherHostTest : public testing::Test {
  public:
   MediaStreamDispatcherHostTest()
-      : old_browser_client_(NULL),
-        thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP),
+      : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP),
+        old_browser_client_(NULL),
         origin_("https://test.com") {
     audio_manager_.reset(
         new media::MockAudioManager(base::ThreadTaskRunnerHandle::Get()));
@@ -422,12 +422,13 @@
   }
 
   scoped_refptr<MockMediaStreamDispatcherHost> host_;
-  std::unique_ptr<media::AudioManager> audio_manager_;
   std::unique_ptr<MediaStreamManager> media_stream_manager_;
+  content::TestBrowserThreadBundle thread_bundle_;
+  std::unique_ptr<media::AudioManager, media::AudioManagerDeleter>
+      audio_manager_;
   MockMediaStreamUIProxy* stream_ui_;
   ContentBrowserClient* old_browser_client_;
   std::unique_ptr<ContentClient> content_client_;
-  content::TestBrowserThreadBundle thread_bundle_;
   content::TestBrowserContext browser_context_;
   media::AudioDeviceNames physical_audio_devices_;
   media::VideoCaptureDevice::Names physical_video_devices_;
diff --git a/content/browser/renderer_host/media/media_stream_manager.cc b/content/browser/renderer_host/media/media_stream_manager.cc
index 34f2edaf..7b75f93 100644
--- a/content/browser/renderer_host/media/media_stream_manager.cc
+++ b/content/browser/renderer_host/media/media_stream_manager.cc
@@ -1128,7 +1128,7 @@
     // its task runner, and MediaStreamManager is deleted on the UI thread,
     // after the IO thread has been stopped.
     base::PostTaskAndReplyWithResult(
-        audio_manager_->GetTaskRunner().get(), FROM_HERE,
+        audio_manager_->GetTaskRunner(), FROM_HERE,
         base::Bind(&media::AudioManager::GetDefaultOutputStreamParameters,
                    base::Unretained(audio_manager_)),
         base::Bind(&MediaStreamManager::PostRequestToUI, base::Unretained(this),
diff --git a/content/browser/renderer_host/media/media_stream_manager_unittest.cc b/content/browser/renderer_host/media/media_stream_manager_unittest.cc
index ff2fada..6e7bec31 100644
--- a/content/browser/renderer_host/media/media_stream_manager_unittest.cc
+++ b/content/browser/renderer_host/media/media_stream_manager_unittest.cc
@@ -11,7 +11,6 @@
 #include "base/location.h"
 #include "base/macros.h"
 #include "base/run_loop.h"
-#include "base/single_thread_task_runner.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
 #include "base/thread_task_runner_handle.h"
@@ -72,7 +71,9 @@
 class MockAudioManager : public AudioManagerPlatform {
  public:
   MockAudioManager()
-      : AudioManagerPlatform(&fake_audio_log_factory_),
+      : AudioManagerPlatform(base::ThreadTaskRunnerHandle::Get(),
+                             base::ThreadTaskRunnerHandle::Get(),
+                             &fake_audio_log_factory_),
         num_output_devices_(2) {}
   ~MockAudioManager() override {}
 
@@ -176,21 +177,21 @@
 class MediaStreamManagerTest : public ::testing::Test {
  public:
   MediaStreamManagerTest()
-      : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP),
-        task_runner_(base::ThreadTaskRunnerHandle::Get()) {
+      : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP) {
     audio_manager_.reset(new MockAudioManager());
     media_stream_manager_.reset(new MediaStreamManager(audio_manager_.get()));
-}
-
-  virtual ~MediaStreamManagerTest() {
+    base::RunLoop().RunUntilIdle();
   }
 
+  ~MediaStreamManagerTest() override {}
+
   MOCK_METHOD1(Response, void(int index));
   void ResponseCallback(int index,
                         const MediaStreamDevices& devices,
                         std::unique_ptr<MediaStreamUIProxy> ui_proxy) {
     Response(index);
-    task_runner_->PostTask(FROM_HERE, run_loop_.QuitClosure());
+    base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
+                                                  run_loop_.QuitClosure());
   }
 
  protected:
@@ -208,10 +209,12 @@
         security_origin, callback);
   }
 
-  std::unique_ptr<MockAudioManager> audio_manager_;
+  // media_stream_manager_ needs to outlive thread_bundle_ because it is a
+  // MessageLoop::DestructionObserver. audio_manager_ needs to outlive
+  // thread_bundle_ because it uses the underlying message loop.
   std::unique_ptr<MediaStreamManager> media_stream_manager_;
   content::TestBrowserThreadBundle thread_bundle_;
-  scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
+  std::unique_ptr<MockAudioManager, media::AudioManagerDeleter> audio_manager_;
   base::RunLoop run_loop_;
 
  private:
@@ -231,7 +234,6 @@
   // No callback is expected.
   media_stream_manager_->CancelRequest(label);
   run_loop_.RunUntilIdle();
-  media_stream_manager_->WillDestroyCurrentMessageLoop();
 }
 
 TEST_F(MediaStreamManagerTest, MakeMultipleRequests) {
diff --git a/content/browser/renderer_host/media/video_capture_host_unittest.cc b/content/browser/renderer_host/media/video_capture_host_unittest.cc
index 933c58d..a5f56706 100644
--- a/content/browser/renderer_host/media/video_capture_host_unittest.cc
+++ b/content/browser/renderer_host/media/video_capture_host_unittest.cc
@@ -274,7 +274,7 @@
 #endif
 
     // Create our own MediaStreamManager.
-    audio_manager_.reset(media::AudioManager::CreateForTesting());
+    audio_manager_ = media::AudioManager::CreateForTesting(task_runner_);
 #ifndef TEST_REAL_CAPTURE_DEVICE
     base::CommandLine::ForCurrentProcess()->AppendSwitch(
         switches::kUseFakeDeviceForMediaStream);
@@ -483,10 +483,13 @@
   scoped_refptr<MockVideoCaptureHost> host_;
 
  private:
+  // media_stream_manager_ needs to outlive thread_bundle_ because it is a
+  // MessageLoop::DestructionObserver. audio_manager_ needs to outlive
+  // thread_bundle_ because it uses the underlying message loop.
   StrictMock<MockMediaStreamRequester> stream_requester_;
-  std::unique_ptr<media::AudioManager> audio_manager_;
   std::unique_ptr<MediaStreamManager> media_stream_manager_;
   content::TestBrowserThreadBundle thread_bundle_;
+  media::ScopedAudioManagerPtr audio_manager_;
   content::TestBrowserContext browser_context_;
   content::TestContentBrowserClient browser_client_;
   scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
diff --git a/content/browser/renderer_host/render_message_filter.cc b/content/browser/renderer_host/render_message_filter.cc
index 4be8b4b..4c06ff0 100644
--- a/content/browser/renderer_host/render_message_filter.cc
+++ b/content/browser/renderer_host/render_message_filter.cc
@@ -247,7 +247,7 @@
 #endif
   // Always query audio device parameters on the audio thread.
   if (message.type() == ViewHostMsg_GetAudioHardwareConfig::ID)
-    return audio_manager_->GetTaskRunner().get();
+    return audio_manager_->GetTaskRunner();
   return NULL;
 }
 
diff --git a/content/browser/speech/speech_recognizer_impl_unittest.cc b/content/browser/speech/speech_recognizer_impl_unittest.cc
index 38f66d1..1675e2e6 100644
--- a/content/browser/speech/speech_recognizer_impl_unittest.cc
+++ b/content/browser/speech/speech_recognizer_impl_unittest.cc
@@ -8,11 +8,11 @@
 #include <vector>
 
 #include "base/sys_byteorder.h"
-#include "content/browser/browser_thread_impl.h"
 #include "content/browser/speech/proto/google_streaming_api.pb.h"
 #include "content/browser/speech/speech_recognition_engine.h"
 #include "content/browser/speech/speech_recognizer_impl.h"
 #include "content/public/browser/speech_recognition_event_listener.h"
+#include "content/public/test/test_browser_thread_bundle.h"
 #include "media/audio/audio_manager_base.h"
 #include "media/audio/fake_audio_input_stream.h"
 #include "media/audio/fake_audio_output_stream.h"
@@ -26,7 +26,6 @@
 
 using media::AudioInputController;
 using media::AudioInputStream;
-using media::AudioManager;
 using media::AudioOutputStream;
 using media::AudioParameters;
 using media::TestAudioInputController;
@@ -38,8 +37,7 @@
                                  public testing::Test {
  public:
   SpeechRecognizerImplTest()
-      : io_thread_(BrowserThread::IO, &message_loop_),
-        recognition_started_(false),
+      : recognition_started_(false),
         recognition_ended_(false),
         result_received_(false),
         audio_started_(false),
@@ -184,10 +182,9 @@
   }
 
  protected:
-  base::MessageLoopForIO message_loop_;
-  BrowserThreadImpl io_thread_;
+  TestBrowserThreadBundle thread_bundle_;
   scoped_refptr<SpeechRecognizerImpl> recognizer_;
-  std::unique_ptr<AudioManager> audio_manager_;
+  media::ScopedAudioManagerPtr audio_manager_;
   bool recognition_started_;
   bool recognition_ended_;
   bool result_received_;
diff --git a/media/audio/alsa/alsa_output_unittest.cc b/media/audio/alsa/alsa_output_unittest.cc
index 1b13863..acf6d28 100644
--- a/media/audio/alsa/alsa_output_unittest.cc
+++ b/media/audio/alsa/alsa_output_unittest.cc
@@ -5,7 +5,10 @@
 #include <stdint.h>
 
 #include "base/macros.h"
+#include "base/run_loop.h"
 #include "base/strings/stringprintf.h"
+#include "base/test/test_message_loop.h"
+#include "base/thread_task_runner_handle.h"
 #include "media/audio/alsa/alsa_output.h"
 #include "media/audio/alsa/alsa_wrapper.h"
 #include "media/audio/alsa/audio_manager_alsa.h"
@@ -72,7 +75,10 @@
 
 class MockAudioManagerAlsa : public AudioManagerAlsa {
  public:
-  MockAudioManagerAlsa() : AudioManagerAlsa(&fake_audio_log_factory_) {}
+  MockAudioManagerAlsa()
+      : AudioManagerAlsa(base::ThreadTaskRunnerHandle::Get(),
+                         base::ThreadTaskRunnerHandle::Get(),
+                         &fake_audio_log_factory_) {}
   MOCK_METHOD0(Init, void());
   MOCK_METHOD0(HasAudioOutputDevices, bool());
   MOCK_METHOD0(HasAudioInputDevices, bool());
@@ -93,12 +99,6 @@
     delete stream;
   }
 
-  // We don't mock this method since all tests will do the same thing
-  // and use the current task runner.
-  scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner() override {
-    return base::MessageLoop::current()->task_runner();
-  }
-
  private:
   FakeAudioLogFactory fake_audio_log_factory_;
 };
@@ -168,9 +168,10 @@
   static void* kFakeHints[];
   static char kGenericSurround50[];
 
+  base::TestMessageLoop message_loop_;
   StrictMock<MockAlsaWrapper> mock_alsa_wrapper_;
-  scoped_ptr<StrictMock<MockAudioManagerAlsa> > mock_manager_;
-  base::MessageLoop message_loop_;
+  std::unique_ptr<StrictMock<MockAudioManagerAlsa>, AudioManagerDeleter>
+      mock_manager_;
   scoped_refptr<media::DataBuffer> packet_;
 
  private:
@@ -442,7 +443,7 @@
   // call Stop() immediately after to ensure we don't run the message loop
   // forever.
   test_stream->Stop();
-  message_loop_.RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
 
   EXPECT_CALL(mock_alsa_wrapper_, PcmClose(kFakeHandle))
       .WillOnce(Return(0));
diff --git a/media/audio/alsa/audio_manager_alsa.cc b/media/audio/alsa/audio_manager_alsa.cc
index 5ddc425..80f8a21 100644
--- a/media/audio/alsa/audio_manager_alsa.cc
+++ b/media/audio/alsa/audio_manager_alsa.cc
@@ -86,8 +86,13 @@
   return HasAnyAlsaAudioDevice(kStreamCapture);
 }
 
-AudioManagerAlsa::AudioManagerAlsa(AudioLogFactory* audio_log_factory)
-    : AudioManagerBase(audio_log_factory),
+AudioManagerAlsa::AudioManagerAlsa(
+    scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+    scoped_refptr<base::SingleThreadTaskRunner> worker_task_runner,
+    AudioLogFactory* audio_log_factory)
+    : AudioManagerBase(std::move(task_runner),
+                       std::move(worker_task_runner),
+                       audio_log_factory),
       wrapper_(new AlsaWrapper()) {
   SetMaxOutputStreamsAllowed(kMaxOutputStreams);
 }
diff --git a/media/audio/alsa/audio_manager_alsa.h b/media/audio/alsa/audio_manager_alsa.h
index d8410fd..5a6ebc1 100644
--- a/media/audio/alsa/audio_manager_alsa.h
+++ b/media/audio/alsa/audio_manager_alsa.h
@@ -18,7 +18,10 @@
 
 class MEDIA_EXPORT AudioManagerAlsa : public AudioManagerBase {
  public:
-  AudioManagerAlsa(AudioLogFactory* audio_log_factory);
+  AudioManagerAlsa(
+      scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+      scoped_refptr<base::SingleThreadTaskRunner> worker_task_runner,
+      AudioLogFactory* audio_log_factory);
 
   static void ShowLinuxAudioInputSettings();
 
diff --git a/media/audio/android/audio_android_unittest.cc b/media/audio/android/audio_android_unittest.cc
index a918a10..8079c166 100644
--- a/media/audio/android/audio_android_unittest.cc
+++ b/media/audio/android/audio_android_unittest.cc
@@ -415,11 +415,16 @@
  public:
   AudioAndroidOutputTest()
       : loop_(new base::MessageLoopForUI()),
-        audio_manager_(AudioManager::CreateForTesting()),
+        audio_manager_(AudioManager::CreateForTesting(loop_->task_runner())),
         audio_output_stream_(NULL) {
+    // Flush the message loop to ensure that AudioManager is fully initialized.
+    loop_->RunUntilIdle();
   }
 
-  ~AudioAndroidOutputTest() override {}
+  ~AudioAndroidOutputTest() override {
+    audio_manager_.reset();
+    loop_->RunUntilIdle();
+  }
 
  protected:
   AudioManager* audio_manager() { return audio_manager_.get(); }
@@ -561,7 +566,7 @@
   }
 
   scoped_ptr<base::MessageLoopForUI> loop_;
-  scoped_ptr<AudioManager> audio_manager_;
+  ScopedAudioManagerPtr audio_manager_;
   AudioParameters audio_output_parameters_;
   AudioOutputStream* audio_output_stream_;
   base::TimeTicks start_time_;
diff --git a/media/audio/android/audio_manager_android.cc b/media/audio/android/audio_manager_android.cc
index 96a7c78..35534b3 100644
--- a/media/audio/android/audio_manager_android.cc
+++ b/media/audio/android/audio_manager_android.cc
@@ -45,12 +45,22 @@
 
 }  // namespace
 
-AudioManager* CreateAudioManager(AudioLogFactory* audio_log_factory) {
-  return new AudioManagerAndroid(audio_log_factory);
+ScopedAudioManagerPtr CreateAudioManager(
+    scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+    scoped_refptr<base::SingleThreadTaskRunner> worker_task_runner,
+    AudioLogFactory* audio_log_factory) {
+  return ScopedAudioManagerPtr(new AudioManagerAndroid(
+      std::move(task_runner), std::move(worker_task_runner),
+      audio_log_factory));
 }
 
-AudioManagerAndroid::AudioManagerAndroid(AudioLogFactory* audio_log_factory)
-    : AudioManagerBase(audio_log_factory),
+AudioManagerAndroid::AudioManagerAndroid(
+    scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+    scoped_refptr<base::SingleThreadTaskRunner> worker_task_runner,
+    AudioLogFactory* audio_log_factory)
+    : AudioManagerBase(std::move(task_runner),
+                       std::move(worker_task_runner),
+                       audio_log_factory),
       communication_mode_is_on_(false),
       output_volume_override_set_(false),
       output_volume_override_(0) {
@@ -68,11 +78,13 @@
 }
 
 AudioManagerAndroid::~AudioManagerAndroid() {
-  // It's safe to post a task here since Shutdown() will wait for all tasks to
-  // complete before returning.
-  GetTaskRunner()->PostTask(FROM_HERE, base::Bind(
-      &AudioManagerAndroid::ShutdownOnAudioThread, base::Unretained(this)));
+  DCHECK(GetTaskRunner()->BelongsToCurrentThread());
   Shutdown();
+
+  DVLOG(2) << "Destroying Java part of the audio manager";
+  Java_AudioManagerAndroid_close(base::android::AttachCurrentThread(),
+                                 j_audio_manager_.obj());
+  j_audio_manager_.Reset();
 }
 
 bool AudioManagerAndroid::HasAudioOutputDevices() {
@@ -337,15 +349,6 @@
       j_audio_manager_.obj());
 }
 
-void AudioManagerAndroid::ShutdownOnAudioThread() {
-  DCHECK(GetTaskRunner()->BelongsToCurrentThread());
-  DVLOG(2) << "Destroying Java part of the audio manager";
-  Java_AudioManagerAndroid_close(
-      base::android::AttachCurrentThread(),
-      j_audio_manager_.obj());
-  j_audio_manager_.Reset();
-}
-
 void AudioManagerAndroid::SetCommunicationAudioModeOn(bool on) {
   Java_AudioManagerAndroid_setCommunicationAudioModeOn(
       base::android::AttachCurrentThread(),
diff --git a/media/audio/android/audio_manager_android.h b/media/audio/android/audio_manager_android.h
index f9b7db25..22b48c8 100644
--- a/media/audio/android/audio_manager_android.h
+++ b/media/audio/android/audio_manager_android.h
@@ -20,7 +20,10 @@
 // Android implemention of AudioManager.
 class MEDIA_EXPORT AudioManagerAndroid : public AudioManagerBase {
  public:
-  explicit AudioManagerAndroid(AudioLogFactory* audio_log_factory);
+  AudioManagerAndroid(
+      scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+      scoped_refptr<base::SingleThreadTaskRunner> worker_task_runner,
+      AudioLogFactory* audio_log_factory);
 
   // Implementation of AudioManager.
   bool HasAudioOutputDevices() override;
@@ -71,7 +74,6 @@
 
  private:
   void InitializeOnAudioThread();
-  void ShutdownOnAudioThread();
 
   bool HasNoAudioInputStreams();
   void SetCommunicationAudioModeOn(bool on);
diff --git a/media/audio/audio_input_controller_unittest.cc b/media/audio/audio_input_controller_unittest.cc
index 6a35d87..36ebc02c 100644
--- a/media/audio/audio_input_controller_unittest.cc
+++ b/media/audio/audio_input_controller_unittest.cc
@@ -67,11 +67,20 @@
 // Test fixture.
 class AudioInputControllerTest : public testing::Test {
  public:
-  AudioInputControllerTest() {}
-  ~AudioInputControllerTest() override {}
+  AudioInputControllerTest()
+      : audio_manager_(
+            AudioManager::CreateForTesting(message_loop_.task_runner())) {
+    // Flush the message loop to ensure that AudioManager is fully initialized.
+    message_loop_.RunUntilIdle();
+  }
+  ~AudioInputControllerTest() override {
+    audio_manager_.reset();
+    message_loop_.RunUntilIdle();
+  }
 
  protected:
   base::MessageLoop message_loop_;
+  ScopedAudioManagerPtr audio_manager_;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(AudioInputControllerTest);
@@ -85,16 +94,12 @@
   EXPECT_CALL(event_handler, OnCreated(NotNull()))
       .WillOnce(QuitMessageLoop(&message_loop_));
 
-  scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting());
   AudioParameters params(AudioParameters::AUDIO_FAKE, kChannelLayout,
                          kSampleRate, kBitsPerSample, kSamplesPerPacket);
 
   scoped_refptr<AudioInputController> controller =
-      AudioInputController::Create(audio_manager.get(),
-                                   &event_handler,
-                                   params,
-                                   AudioManagerBase::kDefaultDeviceId,
-                                   NULL);
+      AudioInputController::Create(audio_manager_.get(), &event_handler, params,
+                                   AudioManagerBase::kDefaultDeviceId, NULL);
   ASSERT_TRUE(controller.get());
 
   // Wait for OnCreated() to fire.
@@ -123,17 +128,13 @@
       .WillRepeatedly(CheckCountAndPostQuitTask(
           &count, 10, message_loop_.task_runner()));
 
-  scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting());
   AudioParameters params(AudioParameters::AUDIO_FAKE, kChannelLayout,
                          kSampleRate, kBitsPerSample, kSamplesPerPacket);
 
   // Creating the AudioInputController should render an OnCreated() call.
   scoped_refptr<AudioInputController> controller =
-      AudioInputController::Create(audio_manager.get(),
-                                   &event_handler,
-                                   params,
-                                   AudioManagerBase::kDefaultDeviceId,
-                                   NULL);
+      AudioInputController::Create(audio_manager_.get(), &event_handler, params,
+                                   AudioManagerBase::kDefaultDeviceId, NULL);
   ASSERT_TRUE(controller.get());
 
   // Start recording and trigger one OnRecording() call.
@@ -176,17 +177,13 @@
       .Times(Exactly(1))
       .WillOnce(QuitMessageLoop(&message_loop_));
 
-  scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting());
   AudioParameters params(AudioParameters::AUDIO_FAKE, kChannelLayout,
                          kSampleRate, kBitsPerSample, kSamplesPerPacket);
 
   // Creating the AudioInputController should render an OnCreated() call.
   scoped_refptr<AudioInputController> controller =
-      AudioInputController::Create(audio_manager.get(),
-                                   &event_handler,
-                                   params,
-                                   AudioManagerBase::kDefaultDeviceId,
-                                   NULL);
+      AudioInputController::Create(audio_manager_.get(), &event_handler, params,
+                                   AudioManagerBase::kDefaultDeviceId, NULL);
   ASSERT_TRUE(controller.get());
 
   // Start recording and trigger one OnRecording() call.
@@ -213,18 +210,14 @@
   EXPECT_CALL(event_handler, OnCreated(NotNull()))
     .Times(Exactly(0));
 
-  scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting());
   AudioParameters params(AudioParameters::AUDIO_FAKE,
                          kChannelLayout,
                          kSampleRate,
                          kBitsPerSample,
                          kSamplesPerPacket * 1000);
   scoped_refptr<AudioInputController> controller =
-      AudioInputController::Create(audio_manager.get(),
-                                   &event_handler,
-                                   params,
-                                   AudioManagerBase::kDefaultDeviceId,
-                                   NULL);
+      AudioInputController::Create(audio_manager_.get(), &event_handler, params,
+                                   AudioManagerBase::kDefaultDeviceId, NULL);
   ASSERT_FALSE(controller.get());
 }
 
@@ -239,18 +232,14 @@
   EXPECT_CALL(event_handler, OnRecording(NotNull()))
       .Times(Exactly(1));
 
-  scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting());
   AudioParameters params(AudioParameters::AUDIO_FAKE,
                          kChannelLayout,
                          kSampleRate,
                          kBitsPerSample,
                          kSamplesPerPacket);
   scoped_refptr<AudioInputController> controller =
-      AudioInputController::Create(audio_manager.get(),
-                                   &event_handler,
-                                   params,
-                                   AudioManagerBase::kDefaultDeviceId,
-                                   NULL);
+      AudioInputController::Create(audio_manager_.get(), &event_handler, params,
+                                   AudioManagerBase::kDefaultDeviceId, NULL);
   ASSERT_TRUE(controller.get());
 
   controller->Record();
diff --git a/media/audio/audio_input_unittest.cc b/media/audio/audio_input_unittest.cc
index abb47ce..5d3ce9f 100644
--- a/media/audio/audio_input_unittest.cc
+++ b/media/audio/audio_input_unittest.cc
@@ -7,10 +7,9 @@
 #include "base/bind.h"
 #include "base/environment.h"
 #include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/message_loop/message_loop.h"
 #include "base/run_loop.h"
-#include "base/synchronization/waitable_event.h"
+#include "base/test/test_message_loop.h"
+#include "base/thread_task_runner_handle.h"
 #include "base/threading/platform_thread.h"
 #include "build/build_config.h"
 #include "media/audio/audio_io.h"
@@ -50,16 +49,16 @@
 };
 
 class AudioInputTest : public testing::Test {
-  public:
-   AudioInputTest() :
-      message_loop_(base::MessageLoop::TYPE_UI),
-      audio_manager_(AudioManager::CreateForTesting()),
-      audio_input_stream_(NULL) {
-    // Wait for the AudioManager to finish any initialization on the audio loop.
+ public:
+  AudioInputTest()
+      : message_loop_(base::MessageLoop::TYPE_UI),
+        audio_manager_(AudioManager::CreateForTesting(
+            base::ThreadTaskRunnerHandle::Get())),
+        audio_input_stream_(NULL) {
     base::RunLoop().RunUntilIdle();
   }
 
-  ~AudioInputTest() override { base::RunLoop().RunUntilIdle(); }
+  ~AudioInputTest() override {}
 
  protected:
   bool InputDevicesAvailable() {
@@ -144,29 +143,12 @@
 
   // Synchronously runs the provided callback/closure on the audio thread.
   void RunOnAudioThread(const base::Closure& closure) {
-    if (!audio_manager_->GetTaskRunner()->BelongsToCurrentThread()) {
-      base::WaitableEvent event(false, false);
-      audio_manager_->GetTaskRunner()->PostTask(
-          FROM_HERE,
-          base::Bind(&AudioInputTest::RunOnAudioThreadImpl,
-                     base::Unretained(this),
-                     closure,
-                     &event));
-      event.Wait();
-    } else {
-      closure.Run();
-    }
-  }
-
-  void RunOnAudioThreadImpl(const base::Closure& closure,
-                            base::WaitableEvent* event) {
     DCHECK(audio_manager_->GetTaskRunner()->BelongsToCurrentThread());
     closure.Run();
-    event->Signal();
   }
 
-  base::MessageLoop message_loop_;
-  scoped_ptr<AudioManager> audio_manager_;
+  base::TestMessageLoop message_loop_;
+  ScopedAudioManagerPtr audio_manager_;
   AudioInputStream* audio_input_stream_;
 
  private:
@@ -222,10 +204,11 @@
   TestInputCallback test_callback;
   OpenAndStartAudioInputStreamOnAudioThread(&test_callback);
 
-  message_loop_.PostDelayedTask(FROM_HERE,
-                                base::MessageLoop::QuitWhenIdleClosure(),
-                                base::TimeDelta::FromMilliseconds(500));
-  message_loop_.Run();
+  base::RunLoop run_loop;
+  base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
+      FROM_HERE, run_loop.QuitClosure(),
+      base::TimeDelta::FromMilliseconds(500));
+  run_loop.Run();
   EXPECT_GE(test_callback.callback_count(), 2);
   EXPECT_FALSE(test_callback.had_error());
 
diff --git a/media/audio/audio_low_latency_input_output_unittest.cc b/media/audio/audio_low_latency_input_output_unittest.cc
index 010b349..8a7728c 100644
--- a/media/audio/audio_low_latency_input_output_unittest.cc
+++ b/media/audio/audio_low_latency_input_output_unittest.cc
@@ -12,6 +12,7 @@
 #include "base/path_service.h"
 #include "base/synchronization/lock.h"
 #include "base/test/test_timeouts.h"
+#include "base/thread_task_runner_handle.h"
 #include "base/time/time.h"
 #include "build/build_config.h"
 #include "media/audio/audio_io.h"
@@ -96,13 +97,12 @@
 // the main thread instead of the audio thread.
 class MockAudioManager : public AudioManagerAnyPlatform {
  public:
-  MockAudioManager() : AudioManagerAnyPlatform(&fake_audio_log_factory_) {}
+  MockAudioManager()
+      : AudioManagerAnyPlatform(base::ThreadTaskRunnerHandle::Get(),
+                                base::ThreadTaskRunnerHandle::Get(),
+                                &fake_audio_log_factory_) {}
   ~MockAudioManager() override {}
 
-  scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner() override {
-    return base::MessageLoop::current()->task_runner();
-  }
-
  private:
   FakeAudioLogFactory fake_audio_log_factory_;
   DISALLOW_COPY_AND_ASSIGN(MockAudioManager);
diff --git a/media/audio/audio_manager.cc b/media/audio/audio_manager.cc
index 5d5f3b3a..573102a0 100644
--- a/media/audio/audio_manager.cc
+++ b/media/audio/audio_manager.cc
@@ -69,30 +69,50 @@
   AudioManagerHelper() {}
   ~AudioManagerHelper() override {}
 
-  void HistogramThreadStatus(ThreadStatus status) {
-    audio_thread_status_ = status;
-    UMA_HISTOGRAM_ENUMERATION("Media.AudioThreadStatus", audio_thread_status_,
-                              THREAD_MAX + 1);
-  }
-
   void StartHangTimer(
-      const scoped_refptr<base::SingleThreadTaskRunner>& monitor_task_runner) {
+      scoped_refptr<base::SingleThreadTaskRunner> monitor_task_runner) {
     CHECK(!monitor_task_runner_);
-    monitor_task_runner_ = monitor_task_runner;
+    CHECK(!audio_task_runner_);
+    CHECK(g_last_created);
+    monitor_task_runner_ = std::move(monitor_task_runner);
+    audio_task_runner_ = g_last_created->GetTaskRunner();
     base::PowerMonitor::Get()->AddObserver(this);
-    failed_pings_ = 0;
+
     io_task_running_ = audio_task_running_ = true;
-    UpdateLastAudioThreadTimeTick();
-    RecordAudioThreadStatus();
+    audio_task_runner_->PostTask(
+        FROM_HERE,
+        base::Bind(&AudioManagerHelper::UpdateLastAudioThreadTimeTick,
+                   base::Unretained(this)));
+    monitor_task_runner_->PostTask(
+        FROM_HERE, base::Bind(&AudioManagerHelper::RecordAudioThreadStatus,
+                              base::Unretained(this)));
   }
 
+  AudioLogFactory* fake_log_factory() { return &fake_log_factory_; }
+
+#if defined(OS_WIN)
+  // This should be called before creating an AudioManager in tests to ensure
+  // that the creating thread is COM initialized.
+  void InitializeCOMForTesting() {
+    com_initializer_for_testing_.reset(new base::win::ScopedCOMInitializer());
+  }
+#endif
+
+#if defined(OS_LINUX)
+  void set_app_name(const std::string& app_name) { app_name_ = app_name; }
+  const std::string& app_name() const { return app_name_; }
+#endif
+
+  void enable_crash_key_logging() { enable_crash_key_logging_ = true; }
+
+ private:
+  // base::PowerObserver overrides.
   // Disable hang detection when the system goes into the suspend state.
   void OnSuspend() override {
     base::AutoLock lock(hang_lock_);
     hang_detection_enabled_ = false;
     failed_pings_ = successful_pings_ = 0;
   }
-
   // Reenable hang detection once the system comes out of the suspend state.
   void OnResume() override {
     base::AutoLock lock(hang_lock_);
@@ -105,19 +125,25 @@
       audio_task_running_ = true;
 
       base::AutoUnlock unlock(hang_lock_);
-      UpdateLastAudioThreadTimeTick();
+      audio_task_runner_->PostTask(
+          FROM_HERE,
+          base::Bind(&AudioManagerHelper::UpdateLastAudioThreadTimeTick,
+                     base::Unretained(this)));
     }
 
     if (!io_task_running_) {
       io_task_running_ = true;
 
       base::AutoUnlock unlock(hang_lock_);
-      RecordAudioThreadStatus();
+      monitor_task_runner_->PostTask(
+          FROM_HERE, base::Bind(&AudioManagerHelper::RecordAudioThreadStatus,
+                                base::Unretained(this)));
     }
   }
 
-  // Runs on |monitor_task_runner| typically, but may be started on any thread.
+  // Runs on |monitor_task_runner|.
   void RecordAudioThreadStatus() {
+    DCHECK(monitor_task_runner_->BelongsToCurrentThread());
     {
       base::AutoLock lock(hang_lock_);
 
@@ -159,8 +185,9 @@
         max_hung_task_time_);
   }
 
-  // Runs on the audio thread typically, but may be started on any thread.
+  // Runs on the audio thread.
   void UpdateLastAudioThreadTimeTick() {
+    DCHECK(audio_task_runner_->BelongsToCurrentThread());
     {
       base::AutoLock lock(hang_lock_);
       last_audio_thread_timer_tick_ = base::TimeTicks::Now();
@@ -176,37 +203,22 @@
     }
 
     // Don't hold the lock while posting the next task.
-    g_last_created->GetTaskRunner()->PostDelayedTask(
+    audio_task_runner_->PostDelayedTask(
         FROM_HERE,
         base::Bind(&AudioManagerHelper::UpdateLastAudioThreadTimeTick,
                    base::Unretained(this)),
         max_hung_task_time_ / 5);
   }
 
-  AudioLogFactory* fake_log_factory() { return &fake_log_factory_; }
-
-#if defined(OS_WIN)
-  // This should be called before creating an AudioManager in tests to ensure
-  // that the creating thread is COM initialized.
-  void InitializeCOMForTesting() {
-    com_initializer_for_testing_.reset(new base::win::ScopedCOMInitializer());
-  }
-#endif
-
-#if defined(OS_LINUX)
-  void set_app_name(const std::string& app_name) {
-    app_name_ = app_name;
+  void HistogramThreadStatus(ThreadStatus status) {
+    DCHECK(monitor_task_runner_->BelongsToCurrentThread());
+    audio_thread_status_ = status;
+    UMA_HISTOGRAM_ENUMERATION("Media.AudioThreadStatus", audio_thread_status_,
+                              THREAD_MAX + 1);
   }
 
-  const std::string& app_name() const {
-    return app_name_;
-  }
-#endif
-
-  void enable_crash_key_logging() { enable_crash_key_logging_ = true; }
-
- private:
   void LogAudioDriverCrashKeys() {
+    DCHECK(monitor_task_runner_->BelongsToCurrentThread());
     DCHECK(enable_crash_key_logging_);
 
 #if defined(OS_WIN)
@@ -228,6 +240,7 @@
 
   const base::TimeDelta max_hung_task_time_ = base::TimeDelta::FromMinutes(1);
   scoped_refptr<base::SingleThreadTaskRunner> monitor_task_runner_;
+  scoped_refptr<base::SingleThreadTaskRunner> audio_task_runner_;
 
   base::Lock hang_lock_;
   bool hang_detection_enabled_ = true;
@@ -255,14 +268,51 @@
 
 }  // namespace
 
-// Forward declaration of the platform specific AudioManager factory function.
-AudioManager* CreateAudioManager(AudioLogFactory* audio_log_factory);
+void AudioManagerDeleter::operator()(const AudioManager* instance) const {
+  CHECK(instance);
+  // We reset g_last_created here instead of in the destructor of AudioManager
+  // because the destructor runs on the audio thread. We want to always change
+  // g_last_created from the main thread.
+  if (g_last_created == instance) {
+    g_last_created = nullptr;
+  } else {
+    // We create multiple instances of AudioManager only when testing.
+    // We should not encounter this case in production.
+    LOG(WARNING) << "Multiple instances of AudioManager detected";
+  }
 
-AudioManager::AudioManager() {}
+  // AudioManager must be destroyed on the audio thread.
+  if (!instance->GetTaskRunner()->DeleteSoon(FROM_HERE, instance)) {
+    LOG(WARNING) << "Failed to delete AudioManager instance.";
+  }
+}
+
+// Forward declaration of the platform specific AudioManager factory function.
+ScopedAudioManagerPtr CreateAudioManager(
+    scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+    scoped_refptr<base::SingleThreadTaskRunner> worker_task_runner,
+    AudioLogFactory* audio_log_factory);
+
+AudioManager::AudioManager(
+    scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+    scoped_refptr<base::SingleThreadTaskRunner> worker_task_runner)
+    : task_runner_(std::move(task_runner)),
+      worker_task_runner_(std::move(worker_task_runner)) {
+  DCHECK(task_runner_);
+  DCHECK(worker_task_runner_);
+
+  if (g_last_created) {
+    // We create multiple instances of AudioManager only when testing.
+    // We should not encounter this case in production.
+    LOG(WARNING) << "Multiple instances of AudioManager detected";
+  }
+  // We always override |g_last_created| irrespective of whether it is already
+  // set or not becuase it represents the last created instance.
+  g_last_created = this;
+}
 
 AudioManager::~AudioManager() {
-  CHECK(!g_last_created || g_last_created == this);
-  g_last_created = nullptr;
+  DCHECK(task_runner_->BelongsToCurrentThread());
 }
 
 // static
@@ -282,37 +332,38 @@
 }
 
 // static
-AudioManager* AudioManager::Create(AudioLogFactory* audio_log_factory) {
-  CHECK(!g_last_created);
-  if (g_audio_manager_factory)
-    g_last_created = g_audio_manager_factory->CreateInstance(audio_log_factory);
-  else
-    g_last_created = CreateAudioManager(audio_log_factory);
+ScopedAudioManagerPtr AudioManager::Create(
+    scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+    scoped_refptr<base::SingleThreadTaskRunner> worker_task_runner,
+    scoped_refptr<base::SingleThreadTaskRunner> monitor_task_runner,
+    AudioLogFactory* audio_log_factory) {
+  DCHECK(task_runner);
+  DCHECK(worker_task_runner);
+  ScopedAudioManagerPtr manager;
+  if (g_audio_manager_factory) {
+    manager = g_audio_manager_factory->CreateInstance(
+        std::move(task_runner), std::move(worker_task_runner),
+        audio_log_factory);
+  } else {
+    manager =
+        CreateAudioManager(std::move(task_runner),
+                           std::move(worker_task_runner), audio_log_factory);
+  }
 
-  return g_last_created;
-}
-
-// static
-AudioManager* AudioManager::CreateWithHangTimer(
-    AudioLogFactory* audio_log_factory,
-    const scoped_refptr<base::SingleThreadTaskRunner>& monitor_task_runner) {
-  AudioManager* manager = Create(audio_log_factory);
-
-// On OSX the audio thread is the UI thread, for which a hang monitor is not
-// necessary or recommended.
-#if !defined(OS_MACOSX)
-  g_helper.Pointer()->StartHangTimer(monitor_task_runner);
-#endif
+  if (monitor_task_runner)
+    g_helper.Pointer()->StartHangTimer(std::move(monitor_task_runner));
 
   return manager;
 }
 
 // static
-AudioManager* AudioManager::CreateForTesting() {
+ScopedAudioManagerPtr AudioManager::CreateForTesting(
+    scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
 #if defined(OS_WIN)
   g_helper.Pointer()->InitializeCOMForTesting();
 #endif
-  return Create(g_helper.Pointer()->fake_log_factory());
+  return Create(task_runner, task_runner, nullptr,
+                g_helper.Pointer()->fake_log_factory());
 }
 
 // static
diff --git a/media/audio/audio_manager.h b/media/audio/audio_manager.h
index d3eea4a..4142581 100644
--- a/media/audio/audio_manager.h
+++ b/media/audio/audio_manager.h
@@ -5,10 +5,12 @@
 #ifndef MEDIA_AUDIO_AUDIO_MANAGER_H_
 #define MEDIA_AUDIO_AUDIO_MANAGER_H_
 
+#include <memory>
 #include <string>
 
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
+#include "base/sequenced_task_runner_helpers.h"
 #include "base/strings/string16.h"
 #include "build/build_config.h"
 #include "media/audio/audio_device_name.h"
@@ -22,9 +24,17 @@
 namespace media {
 
 class AudioInputStream;
+class AudioManager;
 class AudioManagerFactory;
 class AudioOutputStream;
 
+class MEDIA_EXPORT AudioManagerDeleter {
+ public:
+  void operator()(const AudioManager* instance) const;
+};
+using ScopedAudioManagerPtr =
+    std::unique_ptr<AudioManager, AudioManagerDeleter>;
+
 // Manages all audio resources.  Provides some convenience functions that avoid
 // the need to provide iterators over the existing streams.
 //
@@ -34,8 +44,6 @@
 // logged on Windows (this allows us to report driver hangs to Microsoft).
 class MEDIA_EXPORT AudioManager {
  public:
-  virtual ~AudioManager();
-
   // This provides an alternative to the statically linked factory method used
   // to create AudioManager. This is useful for dynamically-linked third
   // party clients seeking to provide a platform-specific implementation of
@@ -46,20 +54,35 @@
   // which must not be NULL.
   static void SetFactory(AudioManagerFactory* factory);
 
-  // Construct the audio manager; only one instance is allowed.  The manager
-  // will forward CreateAudioLog() calls to the provided AudioLogFactory; as
-  // such |audio_log_factory| must outlive the AudioManager.
-  static AudioManager* Create(AudioLogFactory* audio_log_factory);
+  // Construct the audio manager; only one instance is allowed.
+  // The returned instance must be deleted on AudioManager::GetTaskRunnner().
+  //
+  // The manager will forward CreateAudioLog() calls to the provided
+  // AudioLogFactory; as such |audio_log_factory| must outlive the AudioManager.
+  //
+  // The manager will use |task_runner| for audio IO. This same task runner
+  // is returned by GetTaskRunner().
+  // On OS_MACOSX, CoreAudio requires that |task_runner| must belong to the
+  // main thread of the process, which in our case is sadly the browser UI
+  // thread. Failure to execute calls on the right thread leads to crashes and
+  // odd behavior. See http://crbug.com/158170.
+  //
+  // The manager will use |worker_task_runner| for heavyweight tasks.
+  // The |worker_task_runner| may be the same as |task_runner|. This same
+  // task runner is returned by GetWorkerTaskRunner.
+  //
+  // If |monitor_task_runner| is not NULL, a monitor will be scheduled on
+  // |monitor_task_runner| to monitor |task_runner|. See EnableHangMonitor().
+  static ScopedAudioManagerPtr Create(
+      scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+      scoped_refptr<base::SingleThreadTaskRunner> worker_task_runner,
+      scoped_refptr<base::SingleThreadTaskRunner> monitor_task_runner,
+      AudioLogFactory* audio_log_factory);
 
-  // Similar to Create() except also schedules a monitor on the given task
-  // runner to ensure the audio thread is not stuck for more than 60 seconds; if
-  // a hang is detected, the process will be crashed.  See EnableHangMonitor().
-  static AudioManager* CreateWithHangTimer(
-      AudioLogFactory* audio_log_factory,
-      const scoped_refptr<base::SingleThreadTaskRunner>& monitor_task_runner);
-
-  // Similar to Create() except uses a FakeAudioLogFactory for testing.
-  static AudioManager* CreateForTesting();
+  // A convenience wrapper of AudioManager::Create for testing.
+  // The given |task_runner| is shared for both audio io and heavyweight tasks.
+  static ScopedAudioManagerPtr CreateForTesting(
+      scoped_refptr<base::SingleThreadTaskRunner> task_runner);
 
   // Enables non-crash dumps when audio thread hangs are detected.
   // TODO(dalecurtis): There are no callers to this function at present. A list
@@ -178,12 +201,18 @@
       const std::string& device_id) = 0;
 
   // Returns the task runner used for audio IO.
-  virtual scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner() = 0;
+  // TODO(alokp): Rename to task_runner().
+  base::SingleThreadTaskRunner* GetTaskRunner() const {
+    return task_runner_.get();
+  }
 
   // Heavyweight tasks should use GetWorkerTaskRunner() instead of
   // GetTaskRunner(). On most platforms they are the same, but some share the
   // UI loop with the audio IO loop.
-  virtual scoped_refptr<base::SingleThreadTaskRunner> GetWorkerTaskRunner() = 0;
+  // TODO(alokp): Rename to worker_task_runner().
+  base::SingleThreadTaskRunner* GetWorkerTaskRunner() const {
+    return worker_task_runner_.get();
+  }
 
   // Allows clients to listen for device state changes; e.g. preferred sample
   // rate or channel layout changes.  The typical response to receiving this
@@ -230,9 +259,15 @@
       AudioLogFactory::AudioComponent component) = 0;
 
  protected:
-  AudioManager();
+  AudioManager(scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+               scoped_refptr<base::SingleThreadTaskRunner> worker_task_runner);
+  virtual ~AudioManager();
 
  private:
+  friend class base::DeleteHelper<AudioManager>;
+
+  scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
+  scoped_refptr<base::SingleThreadTaskRunner> worker_task_runner_;
   DISALLOW_COPY_AND_ASSIGN(AudioManager);
 };
 
diff --git a/media/audio/audio_manager_base.cc b/media/audio/audio_manager_base.cc
index 8a6acc2..8845585f 100644
--- a/media/audio/audio_manager_base.cc
+++ b/media/audio/audio_manager_base.cc
@@ -89,8 +89,12 @@
   return session_id && device_id.empty();
 }
 
-AudioManagerBase::AudioManagerBase(AudioLogFactory* audio_log_factory)
-    : max_num_output_streams_(kDefaultMaxOutputStreams),
+AudioManagerBase::AudioManagerBase(
+    scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+    scoped_refptr<base::SingleThreadTaskRunner> worker_task_runner,
+    AudioLogFactory* audio_log_factory)
+    : AudioManager(std::move(task_runner), std::move(worker_task_runner)),
+      max_num_output_streams_(kDefaultMaxOutputStreams),
       max_num_input_streams_(kDefaultMaxInputStreams),
       num_output_streams_(0),
       num_input_streams_(0),
@@ -99,42 +103,21 @@
       // block the UI thread when swapping devices.
       output_listeners_(
           base::ObserverList<AudioDeviceListener>::NOTIFY_EXISTING_ONLY),
-      audio_log_factory_(audio_log_factory) {
-}
+      audio_log_factory_(audio_log_factory) {}
 
 AudioManagerBase::~AudioManagerBase() {
-  // The platform specific AudioManager implementation must have already
-  // stopped the audio thread. Otherwise, we may destroy audio streams before
-  // stopping the thread, resulting an unexpected behavior.
-  // This way we make sure activities of the audio streams are all stopped
-  // before we destroy them.
-  CHECK(!audio_thread_);
+  DCHECK(GetTaskRunner()->BelongsToCurrentThread());
+
   // All the output streams should have been deleted.
-  DCHECK_EQ(0, num_output_streams_);
+  CHECK_EQ(0, num_output_streams_);
   // All the input streams should have been deleted.
-  DCHECK_EQ(0, num_input_streams_);
+  CHECK_EQ(0, num_input_streams_);
 }
 
 base::string16 AudioManagerBase::GetAudioInputDeviceModel() {
   return base::string16();
 }
 
-scoped_refptr<base::SingleThreadTaskRunner> AudioManagerBase::GetTaskRunner() {
-  if (!audio_thread_) {
-    audio_thread_.reset(new base::Thread("AudioThread"));
-#if defined(OS_WIN)
-    audio_thread_->init_com_with_mta(true);
-#endif
-    CHECK(audio_thread_->Start());
-  }
-  return audio_thread_->task_runner();
-}
-
-scoped_refptr<base::SingleThreadTaskRunner>
-AudioManagerBase::GetWorkerTaskRunner() {
-  return GetTaskRunner();
-}
-
 AudioOutputStream* AudioManagerBase::MakeAudioOutputStream(
     const AudioParameters& params,
     const std::string& device_id) {
@@ -329,26 +312,8 @@
 }
 
 void AudioManagerBase::Shutdown() {
-  // Only true when we're sharing the UI message loop with the browser.  The UI
-  // loop is no longer running at this time and browser destruction is imminent.
-  auto task_runner = GetTaskRunner();
-  if (task_runner->BelongsToCurrentThread()) {
-    ShutdownOnAudioThread();
-  } else {
-    task_runner->PostTask(FROM_HERE,
-                          base::Bind(&AudioManagerBase::ShutdownOnAudioThread,
-                                     base::Unretained(this)));
-  }
-
-  // Stop() will wait for any posted messages to be processed first.
-  if (audio_thread_) {
-    audio_thread_->Stop();
-    audio_thread_.reset();
-  }
-}
-
-void AudioManagerBase::ShutdownOnAudioThread() {
   DCHECK(GetTaskRunner()->BelongsToCurrentThread());
+  // Close all output streams.
   while (!output_dispatchers_.empty()) {
     output_dispatchers_.back()->dispatcher->Shutdown();
     output_dispatchers_.pop_back();
diff --git a/media/audio/audio_manager_base.h b/media/audio/audio_manager_base.h
index d850447..61292c67 100644
--- a/media/audio/audio_manager_base.h
+++ b/media/audio/audio_manager_base.h
@@ -63,8 +63,6 @@
   ~AudioManagerBase() override;
 
   // AudioManager:
-  scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner() override;
-  scoped_refptr<base::SingleThreadTaskRunner> GetWorkerTaskRunner() override;
   base::string16 GetAudioInputDeviceModel() override;
   void ShowAudioInputSettings() override;
   void GetAudioInputDeviceNames(AudioDeviceNames* device_names) override;
@@ -122,11 +120,14 @@
   int output_stream_count() const { return num_output_streams_; }
 
  protected:
-  AudioManagerBase(AudioLogFactory* audio_log_factory);
+  AudioManagerBase(
+      scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+      scoped_refptr<base::SingleThreadTaskRunner> worker_task_runner,
+      AudioLogFactory* audio_log_factory);
 
-  // Shuts down the audio thread and releases all the audio output dispatchers
-  // on the audio thread.  All audio streams should be freed before Shutdown()
-  // is called.  This must be called in the destructor of every AudioManagerBase
+  // Releases all the audio output dispatchers.
+  // All audio streams should be closed before Shutdown() is called.
+  // This must be called in the destructor of every AudioManagerBase
   // implementation.
   void Shutdown();
 
@@ -162,9 +163,6 @@
 
   class CompareByParams;
 
-  // Called by Shutdown().
-  void ShutdownOnAudioThread();
-
   // Max number of open output streams, modified by
   // SetMaxOutputStreamsAllowed().
   int max_num_output_streams_;
@@ -181,9 +179,6 @@
   // Track output state change listeners.
   base::ObserverList<AudioDeviceListener> output_listeners_;
 
-  // Thread used to interact with audio streams created by this audio manager.
-  scoped_ptr<base::Thread> audio_thread_;
-
   // Map of cached AudioOutputDispatcher instances.  Must only be touched
   // from the audio thread (no locking).
   AudioOutputDispatchers output_dispatchers_;
diff --git a/media/audio/audio_manager_factory.h b/media/audio/audio_manager_factory.h
index 11f1338..72501486 100644
--- a/media/audio/audio_manager_factory.h
+++ b/media/audio/audio_manager_factory.h
@@ -5,11 +5,18 @@
 #ifndef MEDIA_AUDIO_AUDIO_MANAGER_FACTORY_H_
 #define MEDIA_AUDIO_AUDIO_MANAGER_FACTORY_H_
 
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
 #include "media/base/media_export.h"
 
+namespace base {
+class SingleThreadTaskRunner;
+}  // namespace base
+
 namespace media {
 
 class AudioManager;
+class AudioManagerDeleter;
 class AudioLogFactory;
 
 // Allows a platform-specific implementation of AudioManager to be provided in
@@ -20,7 +27,10 @@
 
   // Creates an instance of AudioManager implementation. Caller owns the
   // returned instance. |audio_log_factory| must outlive the returned instance.
-  virtual AudioManager* CreateInstance(AudioLogFactory* audio_log_factory) = 0;
+  virtual scoped_ptr<AudioManager, AudioManagerDeleter> CreateInstance(
+      scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+      scoped_refptr<base::SingleThreadTaskRunner> worker_task_runner,
+      AudioLogFactory* audio_log_factory) = 0;
 };
 
 }  // namespace media
diff --git a/media/audio/audio_manager_factory_unittest.cc b/media/audio/audio_manager_factory_unittest.cc
index 1d13c2e0..b4ceb363 100644
--- a/media/audio/audio_manager_factory_unittest.cc
+++ b/media/audio/audio_manager_factory_unittest.cc
@@ -2,10 +2,10 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "base/memory/scoped_ptr.h"
+#include "base/test/test_message_loop.h"
+#include "base/thread_task_runner_handle.h"
 #include "media/audio/audio_manager.h"
 #include "media/audio/audio_manager_factory.h"
-#include "media/audio/fake_audio_log_factory.h"
 #include "media/audio/fake_audio_manager.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -17,11 +17,17 @@
   FakeAudioManagerFactory() {}
   ~FakeAudioManagerFactory() override {}
 
-  AudioManager* CreateInstance(AudioLogFactory* audio_log_factory) override {
+  ScopedAudioManagerPtr CreateInstance(
+      scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+      scoped_refptr<base::SingleThreadTaskRunner> worker_task_runner,
+      AudioLogFactory* audio_log_factory) override {
+    ScopedAudioManagerPtr instance(
+        new FakeAudioManager(std::move(task_runner),
+                             std::move(worker_task_runner), audio_log_factory));
     // |created_instance_| is used for verifying. Ownership is transferred to
     // caller.
-    created_instance_ = new FakeAudioManager(audio_log_factory);
-    return created_instance_;
+    created_instance_ = instance.get();
+    return instance;
   }
 
   AudioManager* created_instance() { return created_instance_; }
@@ -34,24 +40,29 @@
 
 // Verifies that SetFactory has the intended effect.
 TEST(AudioManagerFactoryTest, CreateInstance) {
-  // Create an audio manager and verify that it is not null.
-  scoped_ptr<AudioManager> manager(AudioManager::CreateForTesting());
-  ASSERT_NE(nullptr, manager.get());
-  manager.reset();
+  {
+    base::TestMessageLoop message_loop;
+    // Create an audio manager and verify that it is not null.
+    ScopedAudioManagerPtr manager =
+        AudioManager::CreateForTesting(base::ThreadTaskRunnerHandle::Get());
+    ASSERT_NE(nullptr, manager.get());
+  }
 
   // Set the factory. Note that ownership of |factory| is transferred to
   // AudioManager.
   FakeAudioManagerFactory* factory = new FakeAudioManagerFactory();
   AudioManager::SetFactory(factory);
-
-  // Create the AudioManager instance. Verify that it matches the instance
-  // provided by the factory.
-  manager.reset(AudioManager::CreateForTesting());
-  ASSERT_NE(nullptr, manager.get());
-  ASSERT_EQ(factory->created_instance(), manager.get());
-
+  {
+    base::TestMessageLoop message_loop;
+    // Create the AudioManager instance. Verify that it matches the instance
+    // provided by the factory.
+    ScopedAudioManagerPtr manager =
+        AudioManager::CreateForTesting(base::ThreadTaskRunnerHandle::Get());
+    ASSERT_NE(nullptr, manager.get());
+    ASSERT_EQ(factory->created_instance(), manager.get());
+  }
   // Reset AudioManagerFactory to prevent factory from persisting to other
-  // tests on the same process. |manager| will reset when scope exits.
+  // tests on the same process.
   AudioManager::ResetFactoryForTesting();
 }
 
diff --git a/media/audio/audio_manager_unittest.cc b/media/audio/audio_manager_unittest.cc
index 894f861..db0196a 100644
--- a/media/audio/audio_manager_unittest.cc
+++ b/media/audio/audio_manager_unittest.cc
@@ -6,7 +6,10 @@
 #include "base/environment.h"
 #include "base/logging.h"
 #include "base/memory/scoped_ptr.h"
+#include "base/run_loop.h"
 #include "base/synchronization/waitable_event.h"
+#include "base/test/test_message_loop.h"
+#include "base/thread_task_runner_handle.h"
 #include "build/build_config.h"
 #include "media/audio/audio_manager.h"
 #include "media/audio/audio_manager_base.h"
@@ -32,6 +35,41 @@
 
 namespace media {
 
+namespace {
+template <typename T>
+struct TestAudioManagerFactory {
+  static ScopedAudioManagerPtr Create(AudioLogFactory* audio_log_factory) {
+    return ScopedAudioManagerPtr(new T(base::ThreadTaskRunnerHandle::Get(),
+                                       base::ThreadTaskRunnerHandle::Get(),
+                                       audio_log_factory));
+  }
+};
+
+#if defined(USE_PULSEAUDIO)
+template <>
+struct TestAudioManagerFactory<AudioManagerPulse> {
+  static ScopedAudioManagerPtr Create(AudioLogFactory* audio_log_factory) {
+    std::unique_ptr<AudioManagerPulse, AudioManagerDeleter> manager(
+        new AudioManagerPulse(base::ThreadTaskRunnerHandle::Get(),
+                              base::ThreadTaskRunnerHandle::Get(),
+                              audio_log_factory));
+    if (!manager->Init())
+      manager.reset();
+    return std::move(manager);
+  }
+};
+#endif  // defined(USE_PULSEAUDIO)
+
+template <>
+struct TestAudioManagerFactory<std::nullptr_t> {
+  static ScopedAudioManagerPtr Create(AudioLogFactory* audio_log_factory) {
+    return AudioManager::Create(base::ThreadTaskRunnerHandle::Get(),
+                                base::ThreadTaskRunnerHandle::Get(), nullptr,
+                                audio_log_factory);
+  }
+};
+}  // namespace
+
 // Test fixture which allows us to override the default enumeration API on
 // Windows.
 class AudioManagerTest : public ::testing::Test {
@@ -77,14 +115,8 @@
   }
 
  protected:
-  AudioManagerTest() : audio_manager_(AudioManager::CreateForTesting()) {
-    // Wait for audio thread initialization to complete.  Otherwise the
-    // enumeration type may not have been set yet.
-    base::WaitableEvent event(false, false);
-    audio_manager_->GetTaskRunner()->PostTask(FROM_HERE, base::Bind(
-        &base::WaitableEvent::Signal, base::Unretained(&event)));
-    event.Wait();
-  }
+  AudioManagerTest() { CreateAudioManagerForTesting(); }
+  ~AudioManagerTest() override {}
 
 #if defined(OS_WIN)
   bool SetMMDeviceEnumeration() {
@@ -149,71 +181,41 @@
     }
   }
 
-  void HasInputDevicesAvailable(bool* has_devices) {
-    *has_devices = audio_manager_->HasAudioInputDevices();
-  }
-
-  void HasOutputDevicesAvailable(bool* has_devices) {
-    *has_devices = audio_manager_->HasAudioOutputDevices();
-  }
-
   bool InputDevicesAvailable() {
-    bool has_devices = false;
-    RunOnAudioThread(base::Bind(&AudioManagerTest::HasInputDevicesAvailable,
-                                base::Unretained(this), &has_devices));
-    return has_devices;
+    return audio_manager_->HasAudioInputDevices();
   }
-
   bool OutputDevicesAvailable() {
-    bool has_devices = false;
-    RunOnAudioThread(base::Bind(&AudioManagerTest::HasOutputDevicesAvailable,
-                                base::Unretained(this), &has_devices));
-    return has_devices;
+    return audio_manager_->HasAudioOutputDevices();
   }
 
-#if defined(USE_ALSA) || defined(USE_PULSEAUDIO)
-  template <class T>
+  template <typename T = std::nullptr_t>
   void CreateAudioManagerForTesting() {
     // Only one AudioManager may exist at a time, so destroy the one we're
     // currently holding before creating a new one.
+    // Flush the message loop to run any shutdown tasks posted by AudioManager.
     audio_manager_.reset();
-    audio_manager_.reset(T::Create(&fake_audio_log_factory_));
-  }
-#endif
+    base::RunLoop().RunUntilIdle();
 
-  // Synchronously runs the provided callback/closure on the audio thread.
-  void RunOnAudioThread(const base::Closure& closure) {
-    if (!audio_manager_->GetTaskRunner()->BelongsToCurrentThread()) {
-      base::WaitableEvent event(false, false);
-      audio_manager_->GetTaskRunner()->PostTask(
-          FROM_HERE,
-          base::Bind(&AudioManagerTest::RunOnAudioThreadImpl,
-                     base::Unretained(this),
-                     closure,
-                     &event));
-      event.Wait();
-    } else {
-      closure.Run();
-    }
+    audio_manager_ =
+        TestAudioManagerFactory<T>::Create(&fake_audio_log_factory_);
+    // A few AudioManager implementations post initialization tasks to
+    // audio thread. Flush the thread to ensure that |audio_manager_| is
+    // initialized and ready to use before returning from this function.
+    // TODO(alokp): We should perhaps do this in AudioManager::Create().
+    base::RunLoop().RunUntilIdle();
   }
 
-  void RunOnAudioThreadImpl(const base::Closure& closure,
-                            base::WaitableEvent* event) {
-    DCHECK(audio_manager_->GetTaskRunner()->BelongsToCurrentThread());
-    closure.Run();
-    event->Signal();
-  }
-
+  base::TestMessageLoop message_loop_;
   FakeAudioLogFactory fake_audio_log_factory_;
-  scoped_ptr<AudioManager> audio_manager_;
+  ScopedAudioManagerPtr audio_manager_;
 };
 
 TEST_F(AudioManagerTest, HandleDefaultDeviceIDs) {
   // Use a fake manager so we can makeup device ids, this will still use the
   // AudioManagerBase code.
-  audio_manager_.reset(new FakeAudioManager(&fake_audio_log_factory_));
-  RunOnAudioThread(base::Bind(&AudioManagerTest::HandleDefaultDeviceIDsTest,
-                              base::Unretained(this)));
+  CreateAudioManagerForTesting<FakeAudioManager>();
+  HandleDefaultDeviceIDsTest();
+  base::RunLoop().RunUntilIdle();
 }
 
 // Test that devices can be enumerated.
@@ -221,10 +223,7 @@
   ABORT_AUDIO_TEST_IF_NOT(InputDevicesAvailable());
 
   AudioDeviceNames device_names;
-  RunOnAudioThread(
-      base::Bind(&AudioManager::GetAudioInputDeviceNames,
-                 base::Unretained(audio_manager_.get()),
-                 &device_names));
+  audio_manager_->GetAudioInputDeviceNames(&device_names);
   CheckDeviceNames(device_names);
 }
 
@@ -233,10 +232,7 @@
   ABORT_AUDIO_TEST_IF_NOT(OutputDevicesAvailable());
 
   AudioDeviceNames device_names;
-  RunOnAudioThread(
-      base::Bind(&AudioManager::GetAudioOutputDeviceNames,
-                 base::Unretained(audio_manager_.get()),
-                 &device_names));
+  audio_manager_->GetAudioOutputDeviceNames(&device_names);
   CheckDeviceNames(device_names);
 }
 
@@ -403,9 +399,7 @@
   ABORT_AUDIO_TEST_IF_NOT(InputDevicesAvailable());
 
   AudioParameters params;
-  RunOnAudioThread(
-      base::Bind(&AudioManagerTest::GetDefaultOutputStreamParameters,
-                 base::Unretained(this), &params));
+  GetDefaultOutputStreamParameters(&params);
   EXPECT_TRUE(params.IsValid());
 #endif  // defined(OS_WIN) || defined(OS_MACOSX)
 }
@@ -415,9 +409,7 @@
   ABORT_AUDIO_TEST_IF_NOT(InputDevicesAvailable() && OutputDevicesAvailable());
 
   AudioDeviceNames device_names;
-  RunOnAudioThread(base::Bind(&AudioManager::GetAudioInputDeviceNames,
-                              base::Unretained(audio_manager_.get()),
-                              &device_names));
+  audio_manager_->GetAudioInputDeviceNames(&device_names);
   bool found_an_associated_device = false;
   for (AudioDeviceNames::iterator it = device_names.begin();
        it != device_names.end();
@@ -425,9 +417,7 @@
     EXPECT_FALSE(it->unique_id.empty());
     EXPECT_FALSE(it->device_name.empty());
     std::string output_device_id;
-    RunOnAudioThread(base::Bind(&AudioManagerTest::GetAssociatedOutputDeviceID,
-                                base::Unretained(this), it->unique_id,
-                                &output_device_id));
+    GetAssociatedOutputDeviceID(it->unique_id, &output_device_id);
     if (!output_device_id.empty()) {
       DVLOG(2) << it->unique_id << " matches with " << output_device_id;
       found_an_associated_device = true;
diff --git a/media/audio/audio_output_controller_unittest.cc b/media/audio/audio_output_controller_unittest.cc
index 1046893..b81cb10 100644
--- a/media/audio/audio_output_controller_unittest.cc
+++ b/media/audio/audio_output_controller_unittest.cc
@@ -10,8 +10,9 @@
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/scoped_ptr.h"
-#include "base/message_loop/message_loop.h"
-#include "base/synchronization/waitable_event.h"
+#include "base/run_loop.h"
+#include "base/test/test_message_loop.h"
+#include "base/thread_task_runner_handle.h"
 #include "media/audio/audio_manager_base.h"
 #include "media/audio/audio_output_controller.h"
 #include "media/audio/audio_parameters.h"
@@ -79,10 +80,6 @@
   AudioSourceCallback* callback_;
 };
 
-ACTION_P(SignalEvent, event) {
-  event->Signal();
-}
-
 static const float kBufferNonZeroData = 1.0f;
 ACTION(PopulateBuffer) {
   arg0->Zero();
@@ -94,29 +91,21 @@
 class AudioOutputControllerTest : public testing::Test {
  public:
   AudioOutputControllerTest()
-      : audio_manager_(AudioManager::CreateForTesting()),
-        create_event_(false, false),
-        play_event_(false, false),
-        read_event_(false, false),
-        pause_event_(false, false) {
+      : audio_manager_(AudioManager::CreateForTesting(
+            base::ThreadTaskRunnerHandle::Get())) {
+    base::RunLoop().RunUntilIdle();
   }
 
   ~AudioOutputControllerTest() override {}
 
  protected:
   void Create(int samples_per_packet) {
-    EXPECT_FALSE(create_event_.IsSignaled());
-    EXPECT_FALSE(play_event_.IsSignaled());
-    EXPECT_FALSE(read_event_.IsSignaled());
-    EXPECT_FALSE(pause_event_.IsSignaled());
-
     params_ = AudioParameters(
         AudioParameters::AUDIO_FAKE, kChannelLayout,
         kSampleRate, kBitsPerSample, samples_per_packet);
 
     if (params_.IsValid()) {
-      EXPECT_CALL(mock_event_handler_, OnCreated())
-          .WillOnce(SignalEvent(&create_event_));
+      EXPECT_CALL(mock_event_handler_, OnCreated());
     }
 
     controller_ = AudioOutputController::Create(
@@ -126,35 +115,33 @@
       controller_->SetVolume(kTestVolume);
 
     EXPECT_EQ(params_.IsValid(), controller_.get() != NULL);
+    base::RunLoop().RunUntilIdle();
   }
 
   void Play() {
     // Expect the event handler to receive one OnPlaying() call.
-    EXPECT_CALL(mock_event_handler_, OnPlaying())
-        .WillOnce(SignalEvent(&play_event_));
+    EXPECT_CALL(mock_event_handler_, OnPlaying());
 
     // During playback, the mock pretends to provide audio data rendered and
     // sent from the render process.
     EXPECT_CALL(mock_sync_reader_, UpdatePendingBytes(_, _)).Times(AtLeast(1));
-    EXPECT_CALL(mock_sync_reader_, Read(_))
-        .WillRepeatedly(DoAll(PopulateBuffer(),
-                              SignalEvent(&read_event_)));
+    EXPECT_CALL(mock_sync_reader_, Read(_)).WillRepeatedly(PopulateBuffer());
     controller_->Play();
+    base::RunLoop().RunUntilIdle();
   }
 
   void Pause() {
     // Expect the event handler to receive one OnPaused() call.
-    EXPECT_CALL(mock_event_handler_, OnPaused())
-        .WillOnce(SignalEvent(&pause_event_));
+    EXPECT_CALL(mock_event_handler_, OnPaused());
 
     controller_->Pause();
+    base::RunLoop().RunUntilIdle();
   }
 
   void ChangeDevice() {
     // Expect the event handler to receive one OnPaying() call and no OnPaused()
     // call.
-    EXPECT_CALL(mock_event_handler_, OnPlaying())
-        .WillOnce(SignalEvent(&play_event_));
+    EXPECT_CALL(mock_event_handler_, OnPlaying());
     EXPECT_CALL(mock_event_handler_, OnPaused())
         .Times(0);
 
@@ -169,8 +156,7 @@
     if (was_playing) {
       // Expect the handler to receive one OnPlaying() call as a result of the
       // stream switching.
-      EXPECT_CALL(mock_event_handler_, OnPlaying())
-          .WillOnce(SignalEvent(&play_event_));
+      EXPECT_CALL(mock_event_handler_, OnPlaying());
     }
 
     EXPECT_CALL(mock_stream_, Open())
@@ -186,6 +172,7 @@
     }
 
     controller_->StartDiverting(&mock_stream_);
+    base::RunLoop().RunUntilIdle();
   }
 
   void ReadDivertedAudioData() {
@@ -201,13 +188,13 @@
     if (was_playing) {
       // Expect the handler to receive one OnPlaying() call as a result of the
       // stream switching back.
-      EXPECT_CALL(mock_event_handler_, OnPlaying())
-          .WillOnce(SignalEvent(&play_event_));
+      EXPECT_CALL(mock_event_handler_, OnPlaying());
     }
 
     EXPECT_CALL(mock_stream_, Close());
 
     controller_->StopDiverting();
+    base::RunLoop().RunUntilIdle();
   }
 
   void SwitchDevice(bool diverting) {
@@ -215,19 +202,22 @@
       // Expect the current stream to close and a new stream to start
       // playing if not diverting. When diverting, nothing happens
       // until diverting is stopped.
-      EXPECT_CALL(mock_event_handler_, OnPlaying())
-          .WillOnce(SignalEvent(&play_event_));
+      EXPECT_CALL(mock_event_handler_, OnPlaying());
     }
 
     controller_->SwitchOutputDevice(AudioManager::GetDefaultDeviceName(),
                                     base::Bind(&base::DoNothing));
+    base::RunLoop().RunUntilIdle();
   }
 
   void Close() {
     EXPECT_CALL(mock_sync_reader_, Close());
 
-    controller_->Close(base::MessageLoop::QuitWhenIdleClosure());
-    base::MessageLoop::current()->Run();
+    base::RunLoop run_loop;
+    base::MessageLoop::current()->PostTask(
+        FROM_HERE, base::Bind(&AudioOutputController::Close, controller_,
+                              run_loop.QuitClosure()));
+    run_loop.Run();
   }
 
   // These help make test sequences more readable.
@@ -237,30 +227,12 @@
   void RevertWasNotPlaying() { Revert(false); }
   void RevertWhilePlaying() { Revert(true); }
 
-  // These synchronize the main thread with key events taking place on other
-  // threads.
-  void WaitForCreate() { create_event_.Wait(); }
-  void WaitForPlay() { play_event_.Wait(); }
-  void WaitForReads() {
-    // Note: Arbitrarily chosen, but more iterations causes tests to take
-    // significantly more time.
-    static const int kNumIterations = 3;
-    for (int i = 0; i < kNumIterations; ++i) {
-      read_event_.Wait();
-    }
-  }
-  void WaitForPause() { pause_event_.Wait(); }
-
  private:
-  base::MessageLoopForIO message_loop_;
-  scoped_ptr<AudioManager> audio_manager_;
+  base::TestMessageLoop message_loop_;
+  ScopedAudioManagerPtr audio_manager_;
   MockAudioOutputControllerEventHandler mock_event_handler_;
   MockAudioOutputControllerSyncReader mock_sync_reader_;
   MockAudioOutputStream mock_stream_;
-  base::WaitableEvent create_event_;
-  base::WaitableEvent play_event_;
-  base::WaitableEvent read_event_;
-  base::WaitableEvent pause_event_;
   AudioParameters params_;
   scoped_refptr<AudioOutputController> controller_;
 
@@ -278,134 +250,84 @@
 
 TEST_F(AudioOutputControllerTest, PlayAndClose) {
   Create(kSamplesPerPacket);
-  WaitForCreate();
   Play();
-  WaitForPlay();
-  WaitForReads();
   Close();
 }
 
 TEST_F(AudioOutputControllerTest, PlayPauseClose) {
   Create(kSamplesPerPacket);
-  WaitForCreate();
   Play();
-  WaitForPlay();
-  WaitForReads();
   Pause();
-  WaitForPause();
   Close();
 }
 
 TEST_F(AudioOutputControllerTest, PlayPausePlayClose) {
   Create(kSamplesPerPacket);
-  WaitForCreate();
   Play();
-  WaitForPlay();
-  WaitForReads();
   Pause();
-  WaitForPause();
   Play();
-  WaitForPlay();
   Close();
 }
 
 TEST_F(AudioOutputControllerTest, PlayDeviceChangeClose) {
   Create(kSamplesPerPacket);
-  WaitForCreate();
   Play();
-  WaitForPlay();
-  WaitForReads();
   ChangeDevice();
-  WaitForPlay();
-  WaitForReads();
   Close();
 }
 
 TEST_F(AudioOutputControllerTest, PlaySwitchDeviceClose) {
   Create(kSamplesPerPacket);
-  WaitForCreate();
   Play();
-  WaitForPlay();
-  WaitForReads();
   SwitchDevice(false);
-  WaitForPlay();
-  WaitForReads();
   Close();
 }
 
 TEST_F(AudioOutputControllerTest, PlayDivertRevertClose) {
   Create(kSamplesPerPacket);
-  WaitForCreate();
   Play();
-  WaitForPlay();
-  WaitForReads();
   DivertWhilePlaying();
-  WaitForPlay();
   ReadDivertedAudioData();
   RevertWhilePlaying();
-  WaitForPlay();
-  WaitForReads();
   Close();
 }
 
 TEST_F(AudioOutputControllerTest, PlayDivertSwitchDeviceRevertClose) {
   Create(kSamplesPerPacket);
-  WaitForCreate();
   Play();
-  WaitForPlay();
-  WaitForReads();
   DivertWhilePlaying();
-  WaitForPlay();
   SwitchDevice(true);
   ReadDivertedAudioData();
   RevertWhilePlaying();
-  WaitForPlay();
-  WaitForReads();
   Close();
 }
 
 TEST_F(AudioOutputControllerTest, PlayDivertRevertDivertRevertClose) {
   Create(kSamplesPerPacket);
-  WaitForCreate();
   Play();
-  WaitForPlay();
-  WaitForReads();
   DivertWhilePlaying();
-  WaitForPlay();
   ReadDivertedAudioData();
   RevertWhilePlaying();
-  WaitForPlay();
-  WaitForReads();
   DivertWhilePlaying();
-  WaitForPlay();
   ReadDivertedAudioData();
   RevertWhilePlaying();
-  WaitForPlay();
-  WaitForReads();
   Close();
 }
 
 TEST_F(AudioOutputControllerTest, DivertPlayPausePlayRevertClose) {
   Create(kSamplesPerPacket);
-  WaitForCreate();
   DivertWillEventuallyBeTwicePlayed();
   Play();
-  WaitForPlay();
   ReadDivertedAudioData();
   Pause();
-  WaitForPause();
   Play();
-  WaitForPlay();
   ReadDivertedAudioData();
   RevertWhilePlaying();
-  WaitForPlay();
-  WaitForReads();
   Close();
 }
 
 TEST_F(AudioOutputControllerTest, DivertRevertClose) {
   Create(kSamplesPerPacket);
-  WaitForCreate();
   DivertNeverPlaying();
   RevertWasNotPlaying();
   Close();
diff --git a/media/audio/audio_output_proxy_unittest.cc b/media/audio/audio_output_proxy_unittest.cc
index f0374618..3c5d0b5 100644
--- a/media/audio/audio_output_proxy_unittest.cc
+++ b/media/audio/audio_output_proxy_unittest.cc
@@ -8,6 +8,7 @@
 
 #include "base/message_loop/message_loop.h"
 #include "base/run_loop.h"
+#include "base/thread_task_runner_handle.h"
 #include "build/build_config.h"
 #include "media/audio/audio_manager.h"
 #include "media/audio/audio_manager_base.h"
@@ -87,10 +88,11 @@
 
 class MockAudioManager : public AudioManagerBase {
  public:
-  MockAudioManager() : AudioManagerBase(&fake_audio_log_factory_) {}
-  virtual ~MockAudioManager() {
-    Shutdown();
-  }
+  MockAudioManager()
+      : AudioManagerBase(base::ThreadTaskRunnerHandle::Get(),
+                         base::ThreadTaskRunnerHandle::Get(),
+                         &fake_audio_log_factory_) {}
+  ~MockAudioManager() override { Shutdown(); }
 
   MOCK_METHOD0(HasAudioOutputDevices, bool());
   MOCK_METHOD0(HasAudioInputDevices, bool());
@@ -143,10 +145,6 @@
 class AudioOutputProxyTest : public testing::Test {
  protected:
   void SetUp() override {
-    EXPECT_CALL(manager_, GetTaskRunner())
-        .WillRepeatedly(Return(message_loop_.task_runner()));
-    EXPECT_CALL(manager_, GetWorkerTaskRunner())
-        .WillRepeatedly(Return(message_loop_.task_runner()));
     // Use a low sample rate and large buffer size when testing otherwise the
     // FakeAudioOutputStream will keep the message loop busy indefinitely; i.e.,
     // RunUntilIdle() will never terminate.
diff --git a/media/audio/cras/audio_manager_cras.cc b/media/audio/cras/audio_manager_cras.cc
index 2a9b77d..0d70a58d 100644
--- a/media/audio/cras/audio_manager_cras.cc
+++ b/media/audio/cras/audio_manager_cras.cc
@@ -135,8 +135,13 @@
   return false;
 }
 
-AudioManagerCras::AudioManagerCras(AudioLogFactory* audio_log_factory)
-    : AudioManagerBase(audio_log_factory),
+AudioManagerCras::AudioManagerCras(
+    scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+    scoped_refptr<base::SingleThreadTaskRunner> worker_task_runner,
+    AudioLogFactory* audio_log_factory)
+    : AudioManagerBase(std::move(task_runner),
+                       std::move(worker_task_runner),
+                       audio_log_factory),
       beamforming_on_device_id_(nullptr),
       beamforming_off_device_id_(nullptr) {
   SetMaxOutputStreamsAllowed(kMaxOutputStreams);
diff --git a/media/audio/cras/audio_manager_cras.h b/media/audio/cras/audio_manager_cras.h
index 6ad4f0e..3383a2f 100644
--- a/media/audio/cras/audio_manager_cras.h
+++ b/media/audio/cras/audio_manager_cras.h
@@ -18,7 +18,10 @@
 
 class MEDIA_EXPORT AudioManagerCras : public AudioManagerBase {
  public:
-  AudioManagerCras(AudioLogFactory* audio_log_factory);
+  AudioManagerCras(
+      scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+      scoped_refptr<base::SingleThreadTaskRunner> worker_task_runner,
+      AudioLogFactory* audio_log_factory);
 
   // AudioManager implementation.
   bool HasAudioOutputDevices() override;
diff --git a/media/audio/cras/cras_input_unittest.cc b/media/audio/cras/cras_input_unittest.cc
index 3735322b0..9062bbda 100644
--- a/media/audio/cras/cras_input_unittest.cc
+++ b/media/audio/cras/cras_input_unittest.cc
@@ -4,11 +4,15 @@
 
 #include <stdint.h>
 
+#include <memory>
 #include <string>
 
 #include "base/macros.h"
+#include "base/run_loop.h"
 #include "base/synchronization/waitable_event.h"
+#include "base/test/test_message_loop.h"
 #include "base/test/test_timeouts.h"
+#include "base/thread_task_runner_handle.h"
 #include "base/time/time.h"
 #include "media/audio/cras/audio_manager_cras.h"
 #include "media/audio/fake_audio_log_factory.h"
@@ -38,7 +42,10 @@
 
 class MockAudioManagerCrasInput : public AudioManagerCras {
  public:
-  MockAudioManagerCrasInput() : AudioManagerCras(&fake_audio_log_factory_) {}
+  MockAudioManagerCrasInput()
+      : AudioManagerCras(base::ThreadTaskRunnerHandle::Get(),
+                         base::ThreadTaskRunnerHandle::Get(),
+                         &fake_audio_log_factory_) {}
 
   // We need to override this function in order to skip checking the number
   // of active output streams. It is because the number of active streams
@@ -57,10 +64,10 @@
  protected:
   CrasInputStreamTest() {
     mock_manager_.reset(new StrictMock<MockAudioManagerCrasInput>());
+    base::RunLoop().RunUntilIdle();
   }
 
-  virtual ~CrasInputStreamTest() {
-  }
+  ~CrasInputStreamTest() override {}
 
   CrasInputStream* CreateStream(ChannelLayout layout) {
     return CreateStream(layout, kTestFramesPerPacket);
@@ -115,7 +122,9 @@
   static const uint32_t kTestFramesPerPacket;
   static const int kTestSampleRate;
 
-  scoped_ptr<StrictMock<MockAudioManagerCrasInput> > mock_manager_;
+  base::TestMessageLoop message_loop_;
+  std::unique_ptr<StrictMock<MockAudioManagerCrasInput>, AudioManagerDeleter>
+      mock_manager_;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(CrasInputStreamTest);
diff --git a/media/audio/cras/cras_unified_unittest.cc b/media/audio/cras/cras_unified_unittest.cc
index cb4d71bf..2bc199ed 100644
--- a/media/audio/cras/cras_unified_unittest.cc
+++ b/media/audio/cras/cras_unified_unittest.cc
@@ -7,8 +7,11 @@
 #include <string>
 
 #include "base/macros.h"
+#include "base/run_loop.h"
 #include "base/synchronization/waitable_event.h"
+#include "base/test/test_message_loop.h"
 #include "base/test/test_timeouts.h"
+#include "base/thread_task_runner_handle.h"
 #include "base/time/time.h"
 #include "media/audio/cras/audio_manager_cras.h"
 #include "media/audio/fake_audio_log_factory.h"
@@ -33,7 +36,10 @@
 
 class MockAudioManagerCras : public AudioManagerCras {
  public:
-  MockAudioManagerCras() : AudioManagerCras(&fake_audio_log_factory_) {}
+  MockAudioManagerCras()
+      : AudioManagerCras(base::ThreadTaskRunnerHandle::Get(),
+                         base::ThreadTaskRunnerHandle::Get(),
+                         &fake_audio_log_factory_) {}
 
   MOCK_METHOD0(Init, void());
   MOCK_METHOD0(HasAudioOutputDevices, bool());
@@ -65,10 +71,10 @@
  protected:
   CrasUnifiedStreamTest() {
     mock_manager_.reset(new StrictMock<MockAudioManagerCras>());
+    base::RunLoop().RunUntilIdle();
   }
 
-  virtual ~CrasUnifiedStreamTest() {
-  }
+  ~CrasUnifiedStreamTest() override {}
 
   CrasUnifiedStream* CreateStream(ChannelLayout layout) {
     return CreateStream(layout, kTestFramesPerPacket);
@@ -91,7 +97,9 @@
   static const AudioParameters::Format kTestFormat;
   static const uint32_t kTestFramesPerPacket;
 
-  scoped_ptr<StrictMock<MockAudioManagerCras> > mock_manager_;
+  base::TestMessageLoop message_loop_;
+  scoped_ptr<StrictMock<MockAudioManagerCras>, AudioManagerDeleter>
+      mock_manager_;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(CrasUnifiedStreamTest);
diff --git a/media/audio/fake_audio_manager.cc b/media/audio/fake_audio_manager.cc
index 3d76401..a4005e1f 100644
--- a/media/audio/fake_audio_manager.cc
+++ b/media/audio/fake_audio_manager.cc
@@ -13,10 +13,18 @@
 
 }  // namespace
 
-FakeAudioManager::FakeAudioManager(AudioLogFactory* audio_log_factory)
-    : AudioManagerBase(audio_log_factory) {}
+FakeAudioManager::FakeAudioManager(
+    scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+    scoped_refptr<base::SingleThreadTaskRunner> worker_task_runner,
+    AudioLogFactory* audio_log_factory)
+    : AudioManagerBase(std::move(task_runner),
+                       std::move(worker_task_runner),
+                       audio_log_factory) {
+  LOG(INFO) << __FUNCTION__;
+}
 
 FakeAudioManager::~FakeAudioManager() {
+  LOG(INFO) << __FUNCTION__;
   Shutdown();
 }
 
diff --git a/media/audio/fake_audio_manager.h b/media/audio/fake_audio_manager.h
index ee055c7..326988c 100644
--- a/media/audio/fake_audio_manager.h
+++ b/media/audio/fake_audio_manager.h
@@ -16,7 +16,10 @@
 
 class MEDIA_EXPORT FakeAudioManager : public AudioManagerBase {
  public:
-  FakeAudioManager(AudioLogFactory* audio_log_factory);
+  FakeAudioManager(
+      scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+      scoped_refptr<base::SingleThreadTaskRunner> worker_task_runner,
+      AudioLogFactory* audio_log_factory);
 
   // Implementation of AudioManager.
   bool HasAudioOutputDevices() override;
diff --git a/media/audio/linux/audio_manager_linux.cc b/media/audio/linux/audio_manager_linux.cc
index 0e7c981..5d9676e 100644
--- a/media/audio/linux/audio_manager_linux.cc
+++ b/media/audio/linux/audio_manager_linux.cc
@@ -4,6 +4,8 @@
 
 #include "base/command_line.h"
 #include "base/metrics/histogram.h"
+#include "media/base/media_switches.h"
+
 #if defined(USE_ALSA)
 #include "media/audio/alsa/audio_manager_alsa.h"
 #else
@@ -15,7 +17,6 @@
 #if defined(USE_PULSEAUDIO)
 #include "media/audio/pulse/audio_manager_pulse.h"
 #endif
-#include "media/base/media_switches.h"
 
 namespace media {
 
@@ -26,27 +27,42 @@
   kAudioIOMax = kCras  // Must always be equal to largest logged entry.
 };
 
-AudioManager* CreateAudioManager(AudioLogFactory* audio_log_factory) {
+ScopedAudioManagerPtr CreateAudioManager(
+    scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+    scoped_refptr<base::SingleThreadTaskRunner> worker_task_runner,
+    AudioLogFactory* audio_log_factory) {
 #if defined(USE_CRAS)
   if (base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kUseCras)) {
     UMA_HISTOGRAM_ENUMERATION("Media.LinuxAudioIO", kCras, kAudioIOMax + 1);
-    return new AudioManagerCras(audio_log_factory);
+    return ScopedAudioManagerPtr(
+        new AudioManagerCras(std::move(task_runner),
+                             std::move(worker_task_runner), audio_log_factory));
   }
 #endif
 
 #if defined(USE_PULSEAUDIO)
-  AudioManager* manager = AudioManagerPulse::Create(audio_log_factory);
-  if (manager) {
+  // Do not move task runners when creating AudioManagerPulse.
+  // If the creation fails, we need to use the task runners to create other
+  // AudioManager implementations.
+  std::unique_ptr<AudioManagerPulse, AudioManagerDeleter> manager(
+      new AudioManagerPulse(task_runner, worker_task_runner,
+                            audio_log_factory));
+  if (manager->Init()) {
     UMA_HISTOGRAM_ENUMERATION("Media.LinuxAudioIO", kPulse, kAudioIOMax + 1);
-    return manager;
+    return std::move(manager);
   }
+  DVLOG(1) << "PulseAudio is not available on the OS";
 #endif
 
 #if defined(USE_ALSA)
   UMA_HISTOGRAM_ENUMERATION("Media.LinuxAudioIO", kAlsa, kAudioIOMax + 1);
-  return new AudioManagerAlsa(audio_log_factory);
+  return ScopedAudioManagerPtr(
+      new AudioManagerAlsa(std::move(task_runner),
+                           std::move(worker_task_runner), audio_log_factory));
 #else
-  return new FakeAudioManager(audio_log_factory);
+  return ScopedAudioManagerPtr(
+      new FakeAudioManager(std::move(task_runner),
+                           std::move(worker_task_runner), audio_log_factory));
 #endif
 }
 
diff --git a/media/audio/mac/audio_auhal_mac_unittest.cc b/media/audio/mac/audio_auhal_mac_unittest.cc
index 73191cd..044116b 100644
--- a/media/audio/mac/audio_auhal_mac_unittest.cc
+++ b/media/audio/mac/audio_auhal_mac_unittest.cc
@@ -4,9 +4,10 @@
 
 #include "base/macros.h"
 #include "base/memory/scoped_ptr.h"
-#include "base/message_loop/message_loop.h"
 #include "base/run_loop.h"
 #include "base/synchronization/waitable_event.h"
+#include "base/test/test_message_loop.h"
+#include "base/thread_task_runner_handle.h"
 #include "media/audio/audio_io.h"
 #include "media/audio/audio_manager.h"
 #include "media/audio/audio_unittest_util.h"
@@ -35,12 +36,13 @@
  public:
   AUHALStreamTest()
       : message_loop_(base::MessageLoop::TYPE_UI),
-        manager_(AudioManager::CreateForTesting()) {
+        manager_(AudioManager::CreateForTesting(
+            base::ThreadTaskRunnerHandle::Get())) {
     // Wait for the AudioManager to finish any initialization on the audio loop.
     base::RunLoop().RunUntilIdle();
   }
 
-  ~AUHALStreamTest() override { base::RunLoop().RunUntilIdle(); }
+  ~AUHALStreamTest() override {}
 
   AudioOutputStream* Create() {
     return manager_->MakeAudioOutputStream(
@@ -52,8 +54,8 @@
   }
 
  protected:
-  base::MessageLoop message_loop_;
-  scoped_ptr<AudioManager> manager_;
+  base::TestMessageLoop message_loop_;
+  ScopedAudioManagerPtr manager_;
   MockAudioSourceCallback source_;
 
  private:
diff --git a/media/audio/mac/audio_low_latency_input_mac_unittest.cc b/media/audio/mac/audio_low_latency_input_mac_unittest.cc
index ba30cf13..7309586 100644
--- a/media/audio/mac/audio_low_latency_input_mac_unittest.cc
+++ b/media/audio/mac/audio_low_latency_input_mac_unittest.cc
@@ -107,12 +107,16 @@
  protected:
   MacAudioInputTest()
       : message_loop_(base::MessageLoop::TYPE_UI),
-        audio_manager_(AudioManager::CreateForTesting()) {
+        audio_manager_(
+            AudioManager::CreateForTesting(message_loop_.task_runner())) {
     // Wait for the AudioManager to finish any initialization on the audio loop.
     base::RunLoop().RunUntilIdle();
   }
 
-  ~MacAudioInputTest() override { base::RunLoop().RunUntilIdle(); }
+  ~MacAudioInputTest() override {
+    audio_manager_.reset();
+    base::RunLoop().RunUntilIdle();
+  }
 
   bool InputDevicesAvailable() {
     return audio_manager_->HasAudioInputDevices();
@@ -146,7 +150,7 @@
   }
 
   base::MessageLoop message_loop_;
-  scoped_ptr<AudioManager> audio_manager_;
+  ScopedAudioManagerPtr audio_manager_;
 };
 
 // Test Create(), Close().
diff --git a/media/audio/mac/audio_manager_mac.cc b/media/audio/mac/audio_manager_mac.cc
index 20cd4c8..0b29dcc13 100644
--- a/media/audio/mac/audio_manager_mac.cc
+++ b/media/audio/mac/audio_manager_mac.cc
@@ -293,18 +293,6 @@
   return GetDefaultDevice(device, false);
 }
 
-template <class T>
-void StopStreams(std::list<T*>* streams) {
-  for (typename std::list<T*>::iterator it = streams->begin();
-       it != streams->end();
-       ++it) {
-    // Stop() is safe to call multiple times, so it doesn't matter if a stream
-    // has already been stopped.
-    (*it)->Stop();
-  }
-  streams->clear();
-}
-
 class AudioManagerMac::AudioPowerObserver : public base::PowerObserver {
  public:
   AudioPowerObserver()
@@ -370,55 +358,29 @@
   DISALLOW_COPY_AND_ASSIGN(AudioPowerObserver);
 };
 
-AudioManagerMac::AudioManagerMac(AudioLogFactory* audio_log_factory)
-    : AudioManagerBase(audio_log_factory),
+AudioManagerMac::AudioManagerMac(
+    scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+    scoped_refptr<base::SingleThreadTaskRunner> worker_task_runner,
+    AudioLogFactory* audio_log_factory)
+    : AudioManagerBase(std::move(task_runner),
+                       std::move(worker_task_runner),
+                       audio_log_factory),
       current_sample_rate_(0),
       current_output_device_(kAudioDeviceUnknown) {
   SetMaxOutputStreamsAllowed(kMaxOutputStreams);
 
-  // CoreAudio calls must occur on the main thread of the process, which in our
-  // case is sadly the browser UI thread.  Failure to execute calls on the right
-  // thread leads to crashes and odd behavior.  See http://crbug.com/158170.
-  // TODO(dalecurtis): We should require the message loop to be passed in.
-  task_runner_ = base::MessageLoopForUI::IsCurrent()
-                     ? base::ThreadTaskRunnerHandle::Get()
-                     : AudioManagerBase::GetTaskRunner();
-
   // Task must be posted last to avoid races from handing out "this" to the
   // audio thread.  Always PostTask even if we're on the right thread since
   // AudioManager creation is on the startup path and this may be slow.
-  task_runner_->PostTask(FROM_HERE,
-                         base::Bind(&AudioManagerMac::InitializeOnAudioThread,
-                                    base::Unretained(this)));
+  GetTaskRunner()->PostTask(
+      FROM_HERE, base::Bind(&AudioManagerMac::InitializeOnAudioThread,
+                            base::Unretained(this)));
 }
 
 AudioManagerMac::~AudioManagerMac() {
-  if (task_runner_->BelongsToCurrentThread()) {
-    ShutdownOnAudioThread();
-  } else {
-    // It's safe to post a task here since Shutdown() will wait for all tasks to
-    // complete before returning.
-    task_runner_->PostTask(FROM_HERE,
-                           base::Bind(&AudioManagerMac::ShutdownOnAudioThread,
-                                      base::Unretained(this)));
-  }
-
   Shutdown();
 }
 
-scoped_refptr<base::SingleThreadTaskRunner> AudioManagerMac::GetTaskRunner() {
-  return task_runner_;
-}
-
-scoped_refptr<base::SingleThreadTaskRunner>
-AudioManagerMac::GetWorkerTaskRunner() {
-  if (!worker_thread_) {
-    worker_thread_.reset(new base::Thread("AudioWorkerThread"));
-    CHECK(worker_thread_->Start());
-  }
-  return worker_thread_->task_runner();
-}
-
 bool AudioManagerMac::HasAudioOutputDevices() {
   return HasAudioHardware(kAudioHardwarePropertyDefaultOutputDevice);
 }
@@ -556,7 +518,7 @@
 
 std::string AudioManagerMac::GetAssociatedOutputDeviceID(
     const std::string& input_device_id) {
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(GetTaskRunner()->BelongsToCurrentThread());
   AudioDeviceID device = GetAudioDeviceIdByUId(true, input_device_id);
   if (device == kAudioObjectUnknown)
     return std::string();
@@ -681,7 +643,7 @@
 }
 
 std::string AudioManagerMac::GetDefaultOutputDeviceID() {
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(GetTaskRunner()->BelongsToCurrentThread());
   AudioDeviceID device_id = kAudioObjectUnknown;
   if (!GetDefaultOutputDevice(&device_id))
     return std::string();
@@ -780,31 +742,12 @@
 }
 
 void AudioManagerMac::InitializeOnAudioThread() {
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(GetTaskRunner()->BelongsToCurrentThread());
   power_observer_.reset(new AudioPowerObserver());
 }
 
-void AudioManagerMac::ShutdownOnAudioThread() {
-  DCHECK(task_runner_->BelongsToCurrentThread());
-  output_device_listener_.reset();
-  power_observer_.reset();
-
-  // Since CoreAudio calls have to run on the UI thread and browser shutdown
-  // doesn't wait for outstanding tasks to complete, we may have input/output
-  // streams still running at shutdown.
-  //
-  // To avoid calls into destructed classes, we need to stop the OS callbacks
-  // by stopping the streams.  Note: The streams are leaked since process
-  // destruction is imminent.
-  //
-  // See http://crbug.com/354139 for crash details.
-  StopStreams(&basic_input_streams_);
-  StopStreams(&low_latency_input_streams_);
-  StopStreams(&output_streams_);
-}
-
 void AudioManagerMac::HandleDeviceChanges() {
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(GetTaskRunner()->BelongsToCurrentThread());
   const int new_sample_rate = HardwareSampleRate();
   AudioDeviceID new_output_device;
   GetDefaultOutputDevice(&new_output_device);
@@ -846,22 +789,22 @@
 }
 
 bool AudioManagerMac::IsSuspending() const {
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(GetTaskRunner()->BelongsToCurrentThread());
   return power_observer_->IsSuspending();
 }
 
 bool AudioManagerMac::ShouldDeferStreamStart() const {
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(GetTaskRunner()->BelongsToCurrentThread());
   return power_observer_->ShouldDeferStreamStart();
 }
 
 bool AudioManagerMac::IsOnBatteryPower() const {
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(GetTaskRunner()->BelongsToCurrentThread());
   return power_observer_->IsOnBatteryPower();
 }
 
 size_t AudioManagerMac::GetNumberOfResumeNotifications() const {
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(GetTaskRunner()->BelongsToCurrentThread());
   return power_observer_->num_resume_notifications();
 }
 
@@ -871,7 +814,7 @@
                                             size_t desired_buffer_size,
                                             bool* size_was_changed,
                                             size_t* io_buffer_frame_size) {
-  DCHECK(task_runner_->BelongsToCurrentThread());
+  DCHECK(GetTaskRunner()->BelongsToCurrentThread());
   const bool is_input = (element == 1);
   DVLOG(1) << "MaybeChangeBufferSize(id=0x" << std::hex << device_id
            << ", is_input=" << is_input << ", desired_buffer_size=" << std::dec
@@ -991,8 +934,13 @@
   AudioManagerBase::ReleaseInputStream(stream);
 }
 
-AudioManager* CreateAudioManager(AudioLogFactory* audio_log_factory) {
-  return new AudioManagerMac(audio_log_factory);
+ScopedAudioManagerPtr CreateAudioManager(
+    scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+    scoped_refptr<base::SingleThreadTaskRunner> worker_task_runner,
+    AudioLogFactory* audio_log_factory) {
+  return ScopedAudioManagerPtr(
+      new AudioManagerMac(std::move(task_runner), std::move(worker_task_runner),
+                          audio_log_factory));
 }
 
 }  // namespace media
diff --git a/media/audio/mac/audio_manager_mac.h b/media/audio/mac/audio_manager_mac.h
index c110538..f8c99e8 100644
--- a/media/audio/mac/audio_manager_mac.h
+++ b/media/audio/mac/audio_manager_mac.h
@@ -26,11 +26,12 @@
 // the AudioManager class.
 class MEDIA_EXPORT AudioManagerMac : public AudioManagerBase {
  public:
-  AudioManagerMac(AudioLogFactory* audio_log_factory);
+  AudioManagerMac(
+      scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+      scoped_refptr<base::SingleThreadTaskRunner> worker_task_runner,
+      AudioLogFactory* audio_log_factory);
 
   // Implementation of AudioManager.
-  scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner() override;
-  scoped_refptr<base::SingleThreadTaskRunner> GetWorkerTaskRunner() override;
   bool HasAudioOutputDevices() override;
   bool HasAudioInputDevices() override;
   void GetAudioInputDeviceNames(AudioDeviceNames* device_names) override;
@@ -117,7 +118,6 @@
 
  private:
   void InitializeOnAudioThread();
-  void ShutdownOnAudioThread();
 
   int ChooseBufferSize(bool is_input, int sample_rate);
 
@@ -127,9 +127,6 @@
 
   scoped_ptr<AudioDeviceListenerMac> output_device_listener_;
 
-  scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
-  scoped_ptr<base::Thread> worker_thread_;
-
   // Track the output sample-rate and the default output device
   // so we can intelligently handle device notifications only when necessary.
   int current_sample_rate_;
@@ -141,8 +138,11 @@
   class AudioPowerObserver;
   scoped_ptr<AudioPowerObserver> power_observer_;
 
-  // Tracks all constructed input and output streams so they can be stopped at
-  // shutdown.  See ShutdownOnAudioThread() for more details.
+  // Tracks all constructed input and output streams.
+  // TODO(alokp): We used to track these streams to close before destruction.
+  // We no longer close the streams, so we may be able to get rid of these
+  // member variables. They are currently used by MaybeChangeBufferSize().
+  // Investigate if we can remove these.
   std::list<AudioInputStream*> basic_input_streams_;
   std::list<AUAudioInputStream*> low_latency_input_streams_;
   std::list<AUHALStream*> output_streams_;
diff --git a/media/audio/mock_audio_manager.cc b/media/audio/mock_audio_manager.cc
index 7183405a..e7726ca 100644
--- a/media/audio/mock_audio_manager.cc
+++ b/media/audio/mock_audio_manager.cc
@@ -11,8 +11,8 @@
 namespace media {
 
 MockAudioManager::MockAudioManager(
-    const scoped_refptr<base::SingleThreadTaskRunner>& task_runner)
-    : task_runner_(task_runner) {}
+    scoped_refptr<base::SingleThreadTaskRunner> task_runner)
+    : AudioManager(task_runner, task_runner) {}
 
 MockAudioManager::~MockAudioManager() {
 }
@@ -63,15 +63,6 @@
   return NULL;
 }
 
-scoped_refptr<base::SingleThreadTaskRunner> MockAudioManager::GetTaskRunner() {
-  return task_runner_;
-}
-
-scoped_refptr<base::SingleThreadTaskRunner>
-MockAudioManager::GetWorkerTaskRunner() {
-  return task_runner_;
-}
-
 void MockAudioManager::AddOutputDeviceChangeListener(
     AudioDeviceListener* listener) {
 }
diff --git a/media/audio/mock_audio_manager.h b/media/audio/mock_audio_manager.h
index 60a8b1e..33f7e5e 100644
--- a/media/audio/mock_audio_manager.h
+++ b/media/audio/mock_audio_manager.h
@@ -11,19 +11,13 @@
 namespace media {
 
 // This class is a simple mock around AudioManager, used exclusively for tests,
-// which has the following purposes:
-// 1) Avoids to use the actual (system and platform dependent) AudioManager.
-//    Some bots does not have input devices, thus using the actual AudioManager
-//    would causing failures on classes which expect that.
-// 2) Allows the mock audio events to be dispatched on an arbitrary thread,
-//    rather than forcing them on the audio thread, easing their handling in
-//    browser tests (Note: sharing a thread can cause deadlocks on production
-//    classes if WaitableEvents or any other form of lock is used for
-//    synchronization purposes).
+// which avoids to use the actual (system and platform dependent) AudioManager.
+// Some bots does not have input devices, thus using the actual AudioManager
+// would causing failures on classes which expect that.
 class MockAudioManager : public media::AudioManager {
  public:
   explicit MockAudioManager(
-      const scoped_refptr<base::SingleThreadTaskRunner>& task_runner);
+      scoped_refptr<base::SingleThreadTaskRunner> task_runner);
 
   bool HasAudioOutputDevices() override;
 
@@ -50,9 +44,6 @@
       const media::AudioParameters& params,
       const std::string& device_id) override;
 
-  scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner() override;
-  scoped_refptr<base::SingleThreadTaskRunner> GetWorkerTaskRunner() override;
-
   void AddOutputDeviceChangeListener(AudioDeviceListener* listener) override;
   void RemoveOutputDeviceChangeListener(AudioDeviceListener* listener) override;
 
@@ -71,8 +62,6 @@
   ~MockAudioManager() override;
 
  private:
-  scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
-
   DISALLOW_COPY_AND_ASSIGN(MockAudioManager);
 };
 
diff --git a/media/audio/pulse/audio_manager_pulse.cc b/media/audio/pulse/audio_manager_pulse.cc
index d6e9543..b96728c 100644
--- a/media/audio/pulse/audio_manager_pulse.cc
+++ b/media/audio/pulse/audio_manager_pulse.cc
@@ -47,18 +47,13 @@
     FILE_PATH_LITERAL("libpulse.so.0");
 #endif
 
-// static
-AudioManager* AudioManagerPulse::Create(AudioLogFactory* audio_log_factory) {
-  scoped_ptr<AudioManagerPulse> ret(new AudioManagerPulse(audio_log_factory));
-  if (ret->Init())
-    return ret.release();
-
-  DVLOG(1) << "PulseAudio is not available on the OS";
-  return NULL;
-}
-
-AudioManagerPulse::AudioManagerPulse(AudioLogFactory* audio_log_factory)
-    : AudioManagerBase(audio_log_factory),
+AudioManagerPulse::AudioManagerPulse(
+    scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+    scoped_refptr<base::SingleThreadTaskRunner> worker_task_runner,
+    AudioLogFactory* audio_log_factory)
+    : AudioManagerBase(std::move(task_runner),
+                       std::move(worker_task_runner),
+                       audio_log_factory),
       input_mainloop_(NULL),
       input_context_(NULL),
       devices_(NULL),
@@ -68,12 +63,20 @@
 
 AudioManagerPulse::~AudioManagerPulse() {
   Shutdown();
-
   // The Pulse objects are the last things to be destroyed since Shutdown()
   // needs them.
   DestroyPulse();
 }
 
+bool AudioManagerPulse::Init() {
+  // TODO(alokp): Investigate if InitPulse can happen on the audio thread.
+  // It currently needs to happen on the main thread so that is InitPulse fails,
+  // we can fallback to ALSA implementation. Initializing it on audio thread
+  // would unblock the main thread and make InitPulse consistent with
+  // DestroyPulse which happens on the audio thread.
+  return InitPulse();
+}
+
 // Implementation of AudioManager.
 bool AudioManagerPulse::HasAudioOutputDevices() {
   AudioDeviceNames devices;
@@ -217,7 +220,7 @@
   return native_input_sample_rate_;
 }
 
-bool AudioManagerPulse::Init() {
+bool AudioManagerPulse::InitPulse() {
   DCHECK(!input_mainloop_);
 
 #if defined(DLOPEN_PULSEAUDIO)
diff --git a/media/audio/pulse/audio_manager_pulse.h b/media/audio/pulse/audio_manager_pulse.h
index 93a1c94..d2f6450 100644
--- a/media/audio/pulse/audio_manager_pulse.h
+++ b/media/audio/pulse/audio_manager_pulse.h
@@ -17,10 +17,12 @@
 
 class MEDIA_EXPORT AudioManagerPulse : public AudioManagerBase {
  public:
-  AudioManagerPulse(AudioLogFactory* audio_log_factory);
-  ~AudioManagerPulse() override;
+  AudioManagerPulse(
+      scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+      scoped_refptr<base::SingleThreadTaskRunner> worker_task_runner,
+      AudioLogFactory* audio_log_factory);
 
-  static AudioManager* Create(AudioLogFactory* audio_log_factory);
+  bool Init();
 
   // Implementation of AudioManager.
   bool HasAudioOutputDevices() override;
@@ -45,12 +47,14 @@
       const std::string& device_id) override;
 
  protected:
+  ~AudioManagerPulse() override;
+
   AudioParameters GetPreferredOutputStreamParameters(
       const std::string& output_device_id,
       const AudioParameters& input_params) override;
 
  private:
-  bool Init();
+  bool InitPulse();
   void DestroyPulse();
 
   void GetAudioDeviceNames(bool input, media::AudioDeviceNames* device_names);
diff --git a/media/audio/sounds/audio_stream_handler_unittest.cc b/media/audio/sounds/audio_stream_handler_unittest.cc
index 1b87ca42..4863bc9 100644
--- a/media/audio/sounds/audio_stream_handler_unittest.cc
+++ b/media/audio/sounds/audio_stream_handler_unittest.cc
@@ -7,8 +7,9 @@
 #include "base/compiler_specific.h"
 #include "base/macros.h"
 #include "base/memory/scoped_ptr.h"
-#include "base/message_loop/message_loop.h"
 #include "base/run_loop.h"
+#include "base/test/test_message_loop.h"
+#include "base/thread_task_runner_handle.h"
 #include "media/audio/audio_io.h"
 #include "media/audio/audio_manager.h"
 #include "media/audio/simple_sources.h"
@@ -25,7 +26,9 @@
   ~AudioStreamHandlerTest() override {}
 
   void SetUp() override {
-    audio_manager_.reset(AudioManager::CreateForTesting());
+    audio_manager_ =
+        AudioManager::CreateForTesting(base::ThreadTaskRunnerHandle::Get());
+    base::RunLoop().RunUntilIdle();
 
     base::StringPiece data(kTestAudioData, arraysize(kTestAudioData));
     audio_stream_handler_.reset(new AudioStreamHandler(data));
@@ -33,7 +36,7 @@
 
   void TearDown() override {
     audio_stream_handler_.reset();
-    audio_manager_.reset();
+    base::RunLoop().RunUntilIdle();
   }
 
   AudioStreamHandler* audio_stream_handler() {
@@ -50,10 +53,9 @@
   }
 
  private:
-  scoped_ptr<AudioManager> audio_manager_;
+  base::TestMessageLoop message_loop_;
+  ScopedAudioManagerPtr audio_manager_;
   scoped_ptr<AudioStreamHandler> audio_stream_handler_;
-
-  base::MessageLoop message_loop_;
 };
 
 TEST_F(AudioStreamHandlerTest, Play) {
diff --git a/media/audio/sounds/sounds_manager_unittest.cc b/media/audio/sounds/sounds_manager_unittest.cc
index 6dfcf119..21f5c65 100644
--- a/media/audio/sounds/sounds_manager_unittest.cc
+++ b/media/audio/sounds/sounds_manager_unittest.cc
@@ -7,10 +7,10 @@
 #include "base/compiler_specific.h"
 #include "base/logging.h"
 #include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/message_loop/message_loop.h"
 #include "base/run_loop.h"
 #include "base/strings/string_piece.h"
+#include "base/test/test_message_loop.h"
+#include "base/thread_task_runner_handle.h"
 #include "media/audio/audio_manager.h"
 #include "media/audio/simple_sources.h"
 #include "media/audio/sounds/audio_stream_handler.h"
@@ -26,13 +26,15 @@
   ~SoundsManagerTest() override {}
 
   void SetUp() override {
-    audio_manager_.reset(AudioManager::CreateForTesting());
+    audio_manager_ =
+        AudioManager::CreateForTesting(base::ThreadTaskRunnerHandle::Get());
     SoundsManager::Create();
+    base::RunLoop().RunUntilIdle();
   }
 
   void TearDown() override {
     SoundsManager::Shutdown();
-    audio_manager_.reset();
+    base::RunLoop().RunUntilIdle();
   }
 
   void SetObserverForTesting(AudioStreamHandler::TestObserver* observer) {
@@ -45,9 +47,8 @@
   }
 
  private:
-  scoped_ptr<AudioManager> audio_manager_;
-
-  base::MessageLoop message_loop_;
+  base::TestMessageLoop message_loop_;
+  ScopedAudioManagerPtr audio_manager_;
 };
 
 TEST_F(SoundsManagerTest, Play) {
diff --git a/media/audio/win/audio_low_latency_input_win_unittest.cc b/media/audio/win/audio_low_latency_input_win_unittest.cc
index 8a9f366..1c67150 100644
--- a/media/audio/win/audio_low_latency_input_win_unittest.cc
+++ b/media/audio/win/audio_low_latency_input_win_unittest.cc
@@ -250,15 +250,31 @@
   DISALLOW_COPY_AND_ASSIGN(ScopedAudioInputStream);
 };
 
+class WinAudioInputTest : public ::testing::Test {
+ public:
+  WinAudioInputTest() {
+    audio_manager_ =
+        AudioManager::CreateForTesting(message_loop_.task_runner());
+    message_loop_.RunUntilIdle();
+  }
+  ~WinAudioInputTest() override {
+    audio_manager_.reset();
+    message_loop_.RunUntilIdle();
+  }
+
+ protected:
+  base::MessageLoop message_loop_;
+  ScopedAudioManagerPtr audio_manager_;
+};
+
 // Verify that we can retrieve the current hardware/mixing sample rate
 // for all available input devices.
-TEST(WinAudioInputTest, WASAPIAudioInputStreamHardwareSampleRate) {
-  scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting());
-  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndInputDevices(audio_manager.get()));
+TEST_F(WinAudioInputTest, WASAPIAudioInputStreamHardwareSampleRate) {
+  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndInputDevices(audio_manager_.get()));
 
   // Retrieve a list of all available input devices.
   media::AudioDeviceNames device_names;
-  audio_manager->GetAudioInputDeviceNames(&device_names);
+  audio_manager_->GetAudioInputDeviceNames(&device_names);
 
   // Scan all available input devices and repeat the same test for all of them.
   for (media::AudioDeviceNames::const_iterator it = device_names.begin();
@@ -272,30 +288,27 @@
 }
 
 // Test Create(), Close() calling sequence.
-TEST(WinAudioInputTest, WASAPIAudioInputStreamCreateAndClose) {
-  scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting());
-  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndInputDevices(audio_manager.get()));
+TEST_F(WinAudioInputTest, WASAPIAudioInputStreamCreateAndClose) {
+  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndInputDevices(audio_manager_.get()));
   ScopedAudioInputStream ais(
-      CreateDefaultAudioInputStream(audio_manager.get()));
+      CreateDefaultAudioInputStream(audio_manager_.get()));
   ais.Close();
 }
 
 // Test Open(), Close() calling sequence.
-TEST(WinAudioInputTest, WASAPIAudioInputStreamOpenAndClose) {
-  scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting());
-  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndInputDevices(audio_manager.get()));
+TEST_F(WinAudioInputTest, WASAPIAudioInputStreamOpenAndClose) {
+  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndInputDevices(audio_manager_.get()));
   ScopedAudioInputStream ais(
-      CreateDefaultAudioInputStream(audio_manager.get()));
+      CreateDefaultAudioInputStream(audio_manager_.get()));
   EXPECT_TRUE(ais->Open());
   ais.Close();
 }
 
 // Test Open(), Start(), Close() calling sequence.
-TEST(WinAudioInputTest, WASAPIAudioInputStreamOpenStartAndClose) {
-  scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting());
-  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndInputDevices(audio_manager.get()));
+TEST_F(WinAudioInputTest, WASAPIAudioInputStreamOpenStartAndClose) {
+  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndInputDevices(audio_manager_.get()));
   ScopedAudioInputStream ais(
-      CreateDefaultAudioInputStream(audio_manager.get()));
+      CreateDefaultAudioInputStream(audio_manager_.get()));
   EXPECT_TRUE(ais->Open());
   MockAudioInputCallback sink;
   ais->Start(&sink);
@@ -303,11 +316,10 @@
 }
 
 // Test Open(), Start(), Stop(), Close() calling sequence.
-TEST(WinAudioInputTest, WASAPIAudioInputStreamOpenStartStopAndClose) {
-  scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting());
-  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndInputDevices(audio_manager.get()));
+TEST_F(WinAudioInputTest, WASAPIAudioInputStreamOpenStartStopAndClose) {
+  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndInputDevices(audio_manager_.get()));
   ScopedAudioInputStream ais(
-      CreateDefaultAudioInputStream(audio_manager.get()));
+      CreateDefaultAudioInputStream(audio_manager_.get()));
   EXPECT_TRUE(ais->Open());
   MockAudioInputCallback sink;
   ais->Start(&sink);
@@ -316,11 +328,10 @@
 }
 
 // Test some additional calling sequences.
-TEST(WinAudioInputTest, WASAPIAudioInputStreamMiscCallingSequences) {
-  scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting());
-  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndInputDevices(audio_manager.get()));
+TEST_F(WinAudioInputTest, WASAPIAudioInputStreamMiscCallingSequences) {
+  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndInputDevices(audio_manager_.get()));
   ScopedAudioInputStream ais(
-      CreateDefaultAudioInputStream(audio_manager.get()));
+      CreateDefaultAudioInputStream(audio_manager_.get()));
   WASAPIAudioInputStream* wais =
       static_cast<WASAPIAudioInputStream*>(ais.get());
 
@@ -344,18 +355,16 @@
   ais.Close();
 }
 
-TEST(WinAudioInputTest, WASAPIAudioInputStreamTestPacketSizes) {
-  scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting());
-  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndInputDevices(audio_manager.get()));
+TEST_F(WinAudioInputTest, WASAPIAudioInputStreamTestPacketSizes) {
+  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndInputDevices(audio_manager_.get()));
 
   int count = 0;
-  base::MessageLoopForUI loop;
 
   // 10 ms packet size.
 
   // Create default WASAPI input stream which records in stereo using
   // the shared mixing rate. The default buffer size is 10ms.
-  AudioInputStreamWrapper aisw(audio_manager.get());
+  AudioInputStreamWrapper aisw(audio_manager_.get());
   ScopedAudioInputStream ais(aisw.Create());
   EXPECT_TRUE(ais->Open());
 
@@ -370,9 +379,9 @@
   // estimate.
   EXPECT_CALL(sink, OnData(ais.get(), NotNull(), _, _))
       .Times(AtLeast(10))
-      .WillRepeatedly(CheckCountAndPostQuitTask(&count, 10, &loop));
+      .WillRepeatedly(CheckCountAndPostQuitTask(&count, 10, &message_loop_));
   ais->Start(&sink);
-  loop.Run();
+  message_loop_.Run();
   ais->Stop();
 
   // Store current packet size (to be used in the subsequent tests).
@@ -390,9 +399,9 @@
 
   EXPECT_CALL(sink, OnData(ais.get(), NotNull(), _, _))
       .Times(AtLeast(10))
-      .WillRepeatedly(CheckCountAndPostQuitTask(&count, 10, &loop));
+      .WillRepeatedly(CheckCountAndPostQuitTask(&count, 10, &message_loop_));
   ais->Start(&sink);
-  loop.Run();
+  message_loop_.Run();
   ais->Stop();
   ais.Close();
 
@@ -406,29 +415,28 @@
 
   EXPECT_CALL(sink, OnData(ais.get(), NotNull(), _, _))
       .Times(AtLeast(10))
-      .WillRepeatedly(CheckCountAndPostQuitTask(&count, 10, &loop));
+      .WillRepeatedly(CheckCountAndPostQuitTask(&count, 10, &message_loop_));
   ais->Start(&sink);
-  loop.Run();
+  message_loop_.Run();
   ais->Stop();
   ais.Close();
 }
 
 // Test that we can capture a stream in loopback.
-TEST(WinAudioInputTest, WASAPIAudioInputStreamLoopback) {
-  scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting());
-  ABORT_AUDIO_TEST_IF_NOT(audio_manager->HasAudioOutputDevices() &&
+TEST_F(WinAudioInputTest, WASAPIAudioInputStreamLoopback) {
+  ABORT_AUDIO_TEST_IF_NOT(audio_manager_->HasAudioOutputDevices() &&
                           CoreAudioUtil::IsSupported());
 
-  AudioParameters params = audio_manager->GetInputStreamParameters(
+  AudioParameters params = audio_manager_->GetInputStreamParameters(
       AudioManagerBase::kLoopbackInputDeviceId);
   EXPECT_EQ(params.effects(), 0);
 
   AudioParameters output_params =
-      audio_manager->GetOutputStreamParameters(std::string());
+      audio_manager_->GetOutputStreamParameters(std::string());
   EXPECT_EQ(params.sample_rate(), output_params.sample_rate());
   EXPECT_EQ(params.channel_layout(), output_params.channel_layout());
 
-  ScopedAudioInputStream stream(audio_manager->MakeAudioInputStream(
+  ScopedAudioInputStream stream(audio_manager_->MakeAudioInputStream(
       params, AudioManagerBase::kLoopbackInputDeviceId));
   ASSERT_TRUE(stream->Open());
   FakeAudioInputCallback sink;
@@ -448,16 +456,15 @@
 // To include disabled tests in test execution, just invoke the test program
 // with --gtest_also_run_disabled_tests or set the GTEST_ALSO_RUN_DISABLED_TESTS
 // environment variable to a value greater than 0.
-TEST(WinAudioInputTest, DISABLED_WASAPIAudioInputStreamRecordToFile) {
-  scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting());
-  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndInputDevices(audio_manager.get()));
+TEST_F(WinAudioInputTest, DISABLED_WASAPIAudioInputStreamRecordToFile) {
+  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndInputDevices(audio_manager_.get()));
 
   // Name of the output PCM file containing captured data. The output file
   // will be stored in the directory containing 'media_unittests.exe'.
   // Example of full name: \src\build\Debug\out_stereo_10sec.pcm.
   const char* file_name = "out_stereo_10sec.pcm";
 
-  AudioInputStreamWrapper aisw(audio_manager.get());
+  AudioInputStreamWrapper aisw(audio_manager_.get());
   ScopedAudioInputStream ais(aisw.Create());
   EXPECT_TRUE(ais->Open());
 
diff --git a/media/audio/win/audio_low_latency_output_win_unittest.cc b/media/audio/win/audio_low_latency_output_win_unittest.cc
index 5b748e7f..c8c6bdf 100644
--- a/media/audio/win/audio_low_latency_output_win_unittest.cc
+++ b/media/audio/win/audio_low_latency_output_win_unittest.cc
@@ -16,7 +16,6 @@
 #include "base/time/time.h"
 #include "base/win/scoped_com_initializer.h"
 #include "media/audio/audio_io.h"
-#include "media/audio/audio_manager.h"
 #include "media/audio/audio_manager_base.h"
 #include "media/audio/audio_unittest_util.h"
 #include "media/audio/mock_audio_source_callback.h"
@@ -228,16 +227,32 @@
   return aos;
 }
 
+class WASAPIAudioOutputStreamTest : public ::testing::Test {
+ public:
+  WASAPIAudioOutputStreamTest() {
+    audio_manager_ =
+        AudioManager::CreateForTesting(message_loop_.task_runner());
+    message_loop_.RunUntilIdle();
+  }
+  ~WASAPIAudioOutputStreamTest() override {
+    audio_manager_.reset();
+    message_loop_.RunUntilIdle();
+  }
+
+ protected:
+  base::MessageLoopForUI message_loop_;
+  ScopedAudioManagerPtr audio_manager_;
+};
+
 // Verify that we can retrieve the current hardware/mixing sample rate
 // for the default audio device.
 // TODO(henrika): modify this test when we support full device enumeration.
-TEST(WASAPIAudioOutputStreamTest, HardwareSampleRate) {
+TEST_F(WASAPIAudioOutputStreamTest, HardwareSampleRate) {
   // Skip this test in exclusive mode since the resulting rate is only utilized
   // for shared mode streams.
   if (ExclusiveModeIsEnabled())
     return;
-  scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting());
-  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndOutputDevices(audio_manager.get()));
+  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndOutputDevices(audio_manager_.get()));
 
   // Default device intended for games, system notification sounds,
   // and voice commands.
@@ -247,27 +262,24 @@
 }
 
 // Test Create(), Close() calling sequence.
-TEST(WASAPIAudioOutputStreamTest, CreateAndClose) {
-  scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting());
-  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndOutputDevices(audio_manager.get()));
-  AudioOutputStream* aos = CreateDefaultAudioOutputStream(audio_manager.get());
+TEST_F(WASAPIAudioOutputStreamTest, CreateAndClose) {
+  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndOutputDevices(audio_manager_.get()));
+  AudioOutputStream* aos = CreateDefaultAudioOutputStream(audio_manager_.get());
   aos->Close();
 }
 
 // Test Open(), Close() calling sequence.
-TEST(WASAPIAudioOutputStreamTest, OpenAndClose) {
-  scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting());
-  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndOutputDevices(audio_manager.get()));
-  AudioOutputStream* aos = CreateDefaultAudioOutputStream(audio_manager.get());
+TEST_F(WASAPIAudioOutputStreamTest, OpenAndClose) {
+  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndOutputDevices(audio_manager_.get()));
+  AudioOutputStream* aos = CreateDefaultAudioOutputStream(audio_manager_.get());
   EXPECT_TRUE(aos->Open());
   aos->Close();
 }
 
 // Test Open(), Start(), Close() calling sequence.
-TEST(WASAPIAudioOutputStreamTest, OpenStartAndClose) {
-  scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting());
-  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndOutputDevices(audio_manager.get()));
-  AudioOutputStream* aos = CreateDefaultAudioOutputStream(audio_manager.get());
+TEST_F(WASAPIAudioOutputStreamTest, OpenStartAndClose) {
+  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndOutputDevices(audio_manager_.get()));
+  AudioOutputStream* aos = CreateDefaultAudioOutputStream(audio_manager_.get());
   EXPECT_TRUE(aos->Open());
   MockAudioSourceCallback source;
   EXPECT_CALL(source, OnError(aos))
@@ -277,10 +289,9 @@
 }
 
 // Test Open(), Start(), Stop(), Close() calling sequence.
-TEST(WASAPIAudioOutputStreamTest, OpenStartStopAndClose) {
-  scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting());
-  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndOutputDevices(audio_manager.get()));
-  AudioOutputStream* aos = CreateDefaultAudioOutputStream(audio_manager.get());
+TEST_F(WASAPIAudioOutputStreamTest, OpenStartStopAndClose) {
+  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndOutputDevices(audio_manager_.get()));
+  AudioOutputStream* aos = CreateDefaultAudioOutputStream(audio_manager_.get());
   EXPECT_TRUE(aos->Open());
   MockAudioSourceCallback source;
   EXPECT_CALL(source, OnError(aos))
@@ -291,10 +302,9 @@
 }
 
 // Test SetVolume(), GetVolume()
-TEST(WASAPIAudioOutputStreamTest, Volume) {
-  scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting());
-  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndOutputDevices(audio_manager.get()));
-  AudioOutputStream* aos = CreateDefaultAudioOutputStream(audio_manager.get());
+TEST_F(WASAPIAudioOutputStreamTest, Volume) {
+  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndOutputDevices(audio_manager_.get()));
+  AudioOutputStream* aos = CreateDefaultAudioOutputStream(audio_manager_.get());
 
   // Initial volume should be full volume (1.0).
   double volume = 0.0;
@@ -327,11 +337,10 @@
 }
 
 // Test some additional calling sequences.
-TEST(WASAPIAudioOutputStreamTest, MiscCallingSequences) {
-  scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting());
-  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndOutputDevices(audio_manager.get()));
+TEST_F(WASAPIAudioOutputStreamTest, MiscCallingSequences) {
+  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndOutputDevices(audio_manager_.get()));
 
-  AudioOutputStream* aos = CreateDefaultAudioOutputStream(audio_manager.get());
+  AudioOutputStream* aos = CreateDefaultAudioOutputStream(audio_manager_.get());
   WASAPIAudioOutputStream* waos = static_cast<WASAPIAudioOutputStream*>(aos);
 
   // Open(), Open() is a valid calling sequence (second call does nothing).
@@ -366,16 +375,13 @@
 }
 
 // Use preferred packet size and verify that rendering starts.
-TEST(WASAPIAudioOutputStreamTest, ValidPacketSize) {
-  scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting());
-  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndOutputDevices(audio_manager.get()));
+TEST_F(WASAPIAudioOutputStreamTest, ValidPacketSize) {
+  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndOutputDevices(audio_manager_.get()));
 
-  base::MessageLoopForUI loop;
   MockAudioSourceCallback source;
-
   // Create default WASAPI output stream which plays out in stereo using
   // the shared mixing rate. The default buffer size is 10ms.
-  AudioOutputStreamWrapper aosw(audio_manager.get());
+  AudioOutputStreamWrapper aosw(audio_manager_.get());
   AudioOutputStream* aos = aosw.Create();
   EXPECT_TRUE(aos->Open());
 
@@ -386,14 +392,15 @@
   // Wait for the first callback and verify its parameters.  Ignore any
   // subsequent callbacks that might arrive.
   EXPECT_CALL(source, OnMoreData(NotNull(), HasValidDelay(bytes_per_packet), 0))
-      .WillOnce(DoAll(QuitLoop(loop.task_runner()),
+      .WillOnce(DoAll(QuitLoop(message_loop_.task_runner()),
                       Return(aosw.samples_per_packet())))
       .WillRepeatedly(Return(0));
 
   aos->Start(&source);
-  loop.PostDelayedTask(FROM_HERE, base::MessageLoop::QuitWhenIdleClosure(),
-                       TestTimeouts::action_timeout());
-  loop.Run();
+  message_loop_.PostDelayedTask(FROM_HERE,
+                                base::MessageLoop::QuitWhenIdleClosure(),
+                                TestTimeouts::action_timeout());
+  message_loop_.Run();
   aos->Stop();
   aos->Close();
 }
@@ -405,11 +412,10 @@
 // with --gtest_also_run_disabled_tests or set the GTEST_ALSO_RUN_DISABLED_TESTS
 // environment variable to a value greater than 0.
 // The test files are approximately 20 seconds long.
-TEST(WASAPIAudioOutputStreamTest, DISABLED_ReadFromStereoFile) {
-  scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting());
-  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndOutputDevices(audio_manager.get()));
+TEST_F(WASAPIAudioOutputStreamTest, DISABLED_ReadFromStereoFile) {
+  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndOutputDevices(audio_manager_.get()));
 
-  AudioOutputStreamWrapper aosw(audio_manager.get());
+  AudioOutputStreamWrapper aosw(audio_manager_.get());
   AudioOutputStream* aos = aosw.Create();
   EXPECT_TRUE(aos->Open());
 
@@ -455,12 +461,11 @@
 // The expected outcomes of each setting in this test has been derived
 // manually using log outputs (--v=1).
 // It's disabled by default because a flag is required to enable exclusive mode.
-TEST(WASAPIAudioOutputStreamTest, DISABLED_ExclusiveModeBufferSizesAt48kHz) {
-  scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting());
-  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndOutputDevices(audio_manager.get()) &&
+TEST_F(WASAPIAudioOutputStreamTest, DISABLED_ExclusiveModeBufferSizesAt48kHz) {
+  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndOutputDevices(audio_manager_.get()) &&
                           ExclusiveModeIsEnabled());
 
-  AudioOutputStreamWrapper aosw(audio_manager.get());
+  AudioOutputStreamWrapper aosw(audio_manager_.get());
 
   // 10ms @ 48kHz shall work.
   // Note that, this is the same size as we can use for shared-mode streaming
@@ -504,12 +509,11 @@
 // The expected outcomes of each setting in this test has been derived
 // manually using log outputs (--v=1).
 // It's disabled by default because a flag is required to enable exclusive mode.
-TEST(WASAPIAudioOutputStreamTest, DISABLED_ExclusiveModeBufferSizesAt44kHz) {
-  scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting());
-  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndOutputDevices(audio_manager.get()) &&
+TEST_F(WASAPIAudioOutputStreamTest, DISABLED_ExclusiveModeBufferSizesAt44kHz) {
+  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndOutputDevices(audio_manager_.get()) &&
                           ExclusiveModeIsEnabled());
 
-  AudioOutputStreamWrapper aosw(audio_manager.get());
+  AudioOutputStreamWrapper aosw(audio_manager_.get());
 
   // 10ms @ 44.1kHz does not work due to misalignment.
   // This test will propose an aligned buffer size of 10.1587ms.
@@ -560,17 +564,15 @@
 // Verify that we can open and start the output stream in exclusive mode at
 // the lowest possible delay at 48kHz.
 // It's disabled by default because a flag is required to enable exclusive mode.
-TEST(WASAPIAudioOutputStreamTest, DISABLED_ExclusiveModeMinBufferSizeAt48kHz) {
-  scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting());
-  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndOutputDevices(audio_manager.get()) &&
+TEST_F(WASAPIAudioOutputStreamTest,
+       DISABLED_ExclusiveModeMinBufferSizeAt48kHz) {
+  ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndOutputDevices(audio_manager_.get()) &&
                           ExclusiveModeIsEnabled());
 
-  base::MessageLoopForUI loop;
   MockAudioSourceCallback source;
-
   // Create exclusive-mode WASAPI output stream which plays out in stereo
   // using the minimum buffer size at 48kHz sample rate.
-  AudioOutputStreamWrapper aosw(audio_manager.get());
+  AudioOutputStreamWrapper aosw(audio_manager_.get());
   AudioOutputStream* aos = aosw.Create(48000, 160);
   EXPECT_TRUE(aos->Open());
 
@@ -580,14 +582,15 @@
 
  // Wait for the first callback and verify its parameters.
   EXPECT_CALL(source, OnMoreData(NotNull(), HasValidDelay(bytes_per_packet), 0))
-      .WillOnce(DoAll(QuitLoop(loop.task_runner()),
+      .WillOnce(DoAll(QuitLoop(message_loop_.task_runner()),
                       Return(aosw.samples_per_packet())))
       .WillRepeatedly(Return(aosw.samples_per_packet()));
 
   aos->Start(&source);
-  loop.PostDelayedTask(FROM_HERE, base::MessageLoop::QuitWhenIdleClosure(),
-                       TestTimeouts::action_timeout());
-  loop.Run();
+  message_loop_.PostDelayedTask(FROM_HERE,
+                                base::MessageLoop::QuitWhenIdleClosure(),
+                                TestTimeouts::action_timeout());
+  message_loop_.Run();
   aos->Stop();
   aos->Close();
 }
@@ -595,16 +598,14 @@
 // Verify that we can open and start the output stream in exclusive mode at
 // the lowest possible delay at 44.1kHz.
 // It's disabled by default because a flag is required to enable exclusive mode.
-TEST(WASAPIAudioOutputStreamTest, DISABLED_ExclusiveModeMinBufferSizeAt44kHz) {
+TEST_F(WASAPIAudioOutputStreamTest,
+       DISABLED_ExclusiveModeMinBufferSizeAt44kHz) {
   ABORT_AUDIO_TEST_IF_NOT(ExclusiveModeIsEnabled());
-  scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting());
 
-  base::MessageLoopForUI loop;
   MockAudioSourceCallback source;
-
   // Create exclusive-mode WASAPI output stream which plays out in stereo
   // using the minimum buffer size at 44.1kHz sample rate.
-  AudioOutputStreamWrapper aosw(audio_manager.get());
+  AudioOutputStreamWrapper aosw(audio_manager_.get());
   AudioOutputStream* aos = aosw.Create(44100, 160);
   EXPECT_TRUE(aos->Open());
 
@@ -614,14 +615,15 @@
 
   // Wait for the first callback and verify its parameters.
   EXPECT_CALL(source, OnMoreData(NotNull(), HasValidDelay(bytes_per_packet), 0))
-      .WillOnce(DoAll(QuitLoop(loop.task_runner()),
+      .WillOnce(DoAll(QuitLoop(message_loop_.task_runner()),
                       Return(aosw.samples_per_packet())))
       .WillRepeatedly(Return(aosw.samples_per_packet()));
 
   aos->Start(&source);
-  loop.PostDelayedTask(FROM_HERE, base::MessageLoop::QuitWhenIdleClosure(),
-                       TestTimeouts::action_timeout());
-  loop.Run();
+  message_loop_.PostDelayedTask(FROM_HERE,
+                                base::MessageLoop::QuitWhenIdleClosure(),
+                                TestTimeouts::action_timeout());
+  message_loop_.Run();
   aos->Stop();
   aos->Close();
 }
diff --git a/media/audio/win/audio_manager_win.cc b/media/audio/win/audio_manager_win.cc
index a3d5ead..df7faf4 100644
--- a/media/audio/win/audio_manager_win.cc
+++ b/media/audio/win/audio_manager_win.cc
@@ -126,14 +126,19 @@
   return (base::win::GetVersion() == base::win::VERSION_VISTA) ? 4 : 3;
 }
 
-AudioManagerWin::AudioManagerWin(AudioLogFactory* audio_log_factory)
-    : AudioManagerBase(audio_log_factory),
+AudioManagerWin::AudioManagerWin(
+    scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+    scoped_refptr<base::SingleThreadTaskRunner> worker_task_runner,
+    AudioLogFactory* audio_log_factory)
+    : AudioManagerBase(std::move(task_runner),
+                       std::move(worker_task_runner),
+                       audio_log_factory),
       // |CoreAudioUtil::IsSupported()| uses static variables to avoid doing
       // multiple initializations.  This is however not thread safe.
       // So, here we call it explicitly before we kick off the audio thread
       // or do any other work.
-      enumeration_type_(CoreAudioUtil::IsSupported() ?
-          kMMDeviceEnumeration : kWaveEnumeration) {
+      enumeration_type_(CoreAudioUtil::IsSupported() ? kMMDeviceEnumeration
+                                                     : kWaveEnumeration) {
   SetMaxOutputStreamsAllowed(kMaxOutputStreams);
 
   // WARNING: This is executed on the UI loop, do not add any code here which
@@ -147,10 +152,6 @@
 }
 
 AudioManagerWin::~AudioManagerWin() {
-  // It's safe to post a task here since Shutdown() will wait for all tasks to
-  // complete before returning.
-  GetTaskRunner()->PostTask(FROM_HERE, base::Bind(
-      &AudioManagerWin::ShutdownOnAudioThread, base::Unretained(this)));
   Shutdown();
 }
 
@@ -174,11 +175,6 @@
   }
 }
 
-void AudioManagerWin::ShutdownOnAudioThread() {
-  DCHECK(GetTaskRunner()->BelongsToCurrentThread());
-  output_device_listener_.reset();
-}
-
 base::string16 AudioManagerWin::GetAudioInputDeviceModel() {
   // Get the default audio capture device and its device interface name.
   DWORD device_id = 0;
@@ -537,8 +533,13 @@
 }
 
 /// static
-AudioManager* CreateAudioManager(AudioLogFactory* audio_log_factory) {
-  return new AudioManagerWin(audio_log_factory);
+ScopedAudioManagerPtr CreateAudioManager(
+    scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+    scoped_refptr<base::SingleThreadTaskRunner> worker_task_runner,
+    AudioLogFactory* audio_log_factory) {
+  return ScopedAudioManagerPtr(
+      new AudioManagerWin(std::move(task_runner), std::move(worker_task_runner),
+                          audio_log_factory));
 }
 
 }  // namespace media
diff --git a/media/audio/win/audio_manager_win.h b/media/audio/win/audio_manager_win.h
index 583a98b..66b24260 100644
--- a/media/audio/win/audio_manager_win.h
+++ b/media/audio/win/audio_manager_win.h
@@ -19,7 +19,10 @@
 // the AudioManager class.
 class MEDIA_EXPORT AudioManagerWin : public AudioManagerBase {
  public:
-  AudioManagerWin(AudioLogFactory* audio_log_factory);
+  AudioManagerWin(
+      scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+      scoped_refptr<base::SingleThreadTaskRunner> worker_task_runner,
+      AudioLogFactory* audio_log_factory);
 
   // Implementation of AudioManager.
   bool HasAudioOutputDevices() override;
@@ -85,7 +88,6 @@
   // Helper methods for performing expensive initialization tasks on the audio
   // thread instead of on the UI thread which AudioManager is constructed on.
   void InitializeOnAudioThread();
-  void ShutdownOnAudioThread();
 
   void GetAudioDeviceNamesImpl(bool input, AudioDeviceNames* device_names);
 
diff --git a/media/audio/win/audio_output_win_unittest.cc b/media/audio/win/audio_output_win_unittest.cc
index 0c59d9b3..8fca2f55 100644
--- a/media/audio/win/audio_output_win_unittest.cc
+++ b/media/audio/win/audio_output_win_unittest.cc
@@ -9,6 +9,7 @@
 
 #include "base/base_paths.h"
 #include "base/memory/aligned_memory.h"
+#include "base/message_loop/message_loop.h"
 #include "base/sync_socket.h"
 #include "base/win/scoped_com_initializer.h"
 #include "base/win/windows_version.h"
@@ -143,6 +144,23 @@
   uint32_t size_;
 };
 
+class WinAudioTest : public ::testing::Test {
+ public:
+  WinAudioTest() {
+    audio_manager_ =
+        AudioManager::CreateForTesting(message_loop_.task_runner());
+    message_loop_.RunUntilIdle();
+  }
+  ~WinAudioTest() override {
+    audio_manager_.reset();
+    message_loop_.RunUntilIdle();
+  }
+
+ protected:
+  base::MessageLoop message_loop_;
+  ScopedAudioManagerPtr audio_manager_;
+};
+
 // ===========================================================================
 // Validation of AudioManager::AUDIO_PCM_LINEAR
 //
@@ -152,11 +170,10 @@
 // at some point, possibly when the connection goes idle.
 
 // Test that can it be created and closed.
-TEST(WinAudioTest, PCMWaveStreamGetAndClose) {
-  scoped_ptr<AudioManager> audio_man(AudioManager::CreateForTesting());
-  ABORT_AUDIO_TEST_IF_NOT(audio_man->HasAudioOutputDevices());
+TEST_F(WinAudioTest, PCMWaveStreamGetAndClose) {
+  ABORT_AUDIO_TEST_IF_NOT(audio_manager_->HasAudioOutputDevices());
 
-  AudioOutputStream* oas = audio_man->MakeAudioOutputStream(
+  AudioOutputStream* oas = audio_manager_->MakeAudioOutputStream(
       AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, CHANNEL_LAYOUT_STEREO,
                       8000, 16, 256),
       std::string());
@@ -165,44 +182,53 @@
 }
 
 // Test that can it be cannot be created with invalid parameters.
-TEST(WinAudioTest, SanityOnMakeParams) {
-  scoped_ptr<AudioManager> audio_man(AudioManager::CreateForTesting());
-  ABORT_AUDIO_TEST_IF_NOT(audio_man->HasAudioOutputDevices());
+TEST_F(WinAudioTest, SanityOnMakeParams) {
+  ABORT_AUDIO_TEST_IF_NOT(audio_manager_->HasAudioOutputDevices());
 
   AudioParameters::Format fmt = AudioParameters::AUDIO_PCM_LINEAR;
-  EXPECT_TRUE(NULL == audio_man->MakeAudioOutputStream(
-      AudioParameters(fmt, CHANNEL_LAYOUT_UNSUPPORTED, 8000, 16, 256),
-      std::string()));
-  EXPECT_TRUE(NULL == audio_man->MakeAudioOutputStream(
-      AudioParameters(fmt, CHANNEL_LAYOUT_MONO, 1024 * 1024, 16, 256),
-      std::string()));
-  EXPECT_TRUE(NULL == audio_man->MakeAudioOutputStream(
-      AudioParameters(fmt, CHANNEL_LAYOUT_STEREO, 8000, 80, 256),
-      std::string()));
-  EXPECT_TRUE(NULL == audio_man->MakeAudioOutputStream(
-      AudioParameters(fmt, CHANNEL_LAYOUT_UNSUPPORTED, 8000, 16, 256),
-      std::string()));
-  EXPECT_TRUE(NULL == audio_man->MakeAudioOutputStream(
-      AudioParameters(fmt, CHANNEL_LAYOUT_STEREO, -8000, 16, 256),
-      std::string()));
-  EXPECT_TRUE(NULL == audio_man->MakeAudioOutputStream(
-      AudioParameters(fmt, CHANNEL_LAYOUT_MONO, 8000, 16, -100),
-      std::string()));
-  EXPECT_TRUE(NULL == audio_man->MakeAudioOutputStream(
-      AudioParameters(fmt, CHANNEL_LAYOUT_MONO, 8000, 16, 0),
-      std::string()));
-  EXPECT_TRUE(NULL == audio_man->MakeAudioOutputStream(
-      AudioParameters(fmt, CHANNEL_LAYOUT_MONO, 8000, 16,
-                      media::limits::kMaxSamplesPerPacket + 1),
-      std::string()));
+  EXPECT_TRUE(
+      NULL ==
+      audio_manager_->MakeAudioOutputStream(
+          AudioParameters(fmt, CHANNEL_LAYOUT_UNSUPPORTED, 8000, 16, 256),
+          std::string()));
+  EXPECT_TRUE(
+      NULL ==
+      audio_manager_->MakeAudioOutputStream(
+          AudioParameters(fmt, CHANNEL_LAYOUT_MONO, 1024 * 1024, 16, 256),
+          std::string()));
+  EXPECT_TRUE(NULL ==
+              audio_manager_->MakeAudioOutputStream(
+                  AudioParameters(fmt, CHANNEL_LAYOUT_STEREO, 8000, 80, 256),
+                  std::string()));
+  EXPECT_TRUE(
+      NULL ==
+      audio_manager_->MakeAudioOutputStream(
+          AudioParameters(fmt, CHANNEL_LAYOUT_UNSUPPORTED, 8000, 16, 256),
+          std::string()));
+  EXPECT_TRUE(NULL ==
+              audio_manager_->MakeAudioOutputStream(
+                  AudioParameters(fmt, CHANNEL_LAYOUT_STEREO, -8000, 16, 256),
+                  std::string()));
+  EXPECT_TRUE(NULL ==
+              audio_manager_->MakeAudioOutputStream(
+                  AudioParameters(fmt, CHANNEL_LAYOUT_MONO, 8000, 16, -100),
+                  std::string()));
+  EXPECT_TRUE(NULL ==
+              audio_manager_->MakeAudioOutputStream(
+                  AudioParameters(fmt, CHANNEL_LAYOUT_MONO, 8000, 16, 0),
+                  std::string()));
+  EXPECT_TRUE(NULL ==
+              audio_manager_->MakeAudioOutputStream(
+                  AudioParameters(fmt, CHANNEL_LAYOUT_MONO, 8000, 16,
+                                  media::limits::kMaxSamplesPerPacket + 1),
+                  std::string()));
 }
 
 // Test that it can be opened and closed.
-TEST(WinAudioTest, PCMWaveStreamOpenAndClose) {
-  scoped_ptr<AudioManager> audio_man(AudioManager::CreateForTesting());
-  ABORT_AUDIO_TEST_IF_NOT(audio_man->HasAudioOutputDevices());
+TEST_F(WinAudioTest, PCMWaveStreamOpenAndClose) {
+  ABORT_AUDIO_TEST_IF_NOT(audio_manager_->HasAudioOutputDevices());
 
-  AudioOutputStream* oas = audio_man->MakeAudioOutputStream(
+  AudioOutputStream* oas = audio_manager_->MakeAudioOutputStream(
       AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, CHANNEL_LAYOUT_STEREO,
                       8000, 16, 256),
       std::string());
@@ -212,11 +238,10 @@
 }
 
 // Test that it has a maximum packet size.
-TEST(WinAudioTest, PCMWaveStreamOpenLimit) {
-  scoped_ptr<AudioManager> audio_man(AudioManager::CreateForTesting());
-  ABORT_AUDIO_TEST_IF_NOT(audio_man->HasAudioOutputDevices());
+TEST_F(WinAudioTest, PCMWaveStreamOpenLimit) {
+  ABORT_AUDIO_TEST_IF_NOT(audio_manager_->HasAudioOutputDevices());
 
-  AudioOutputStream* oas = audio_man->MakeAudioOutputStream(
+  AudioOutputStream* oas = audio_manager_->MakeAudioOutputStream(
       AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, CHANNEL_LAYOUT_STEREO,
                       8000, 16, 1024 * 1024 * 1024),
       std::string());
@@ -228,11 +253,10 @@
 // Test potential deadlock situation if the source is slow or blocks for some
 // time. The actual EXPECT_GT are mostly meaningless and the real test is that
 // the test completes in reasonable time.
-TEST(WinAudioTest, PCMWaveSlowSource) {
-  scoped_ptr<AudioManager> audio_man(AudioManager::CreateForTesting());
-  ABORT_AUDIO_TEST_IF_NOT(audio_man->HasAudioOutputDevices());
+TEST_F(WinAudioTest, PCMWaveSlowSource) {
+  ABORT_AUDIO_TEST_IF_NOT(audio_manager_->HasAudioOutputDevices());
 
-  AudioOutputStream* oas = audio_man->MakeAudioOutputStream(
+  AudioOutputStream* oas = audio_manager_->MakeAudioOutputStream(
       AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, CHANNEL_LAYOUT_MONO,
                       16000, 16, 256),
       std::string());
@@ -253,12 +277,11 @@
 // Test another potential deadlock situation if the thread that calls Start()
 // gets paused. This test is best when run over RDP with audio enabled. See
 // bug 19276 for more details.
-TEST(WinAudioTest, PCMWaveStreamPlaySlowLoop) {
-  scoped_ptr<AudioManager> audio_man(AudioManager::CreateForTesting());
-  ABORT_AUDIO_TEST_IF_NOT(audio_man->HasAudioOutputDevices());
+TEST_F(WinAudioTest, PCMWaveStreamPlaySlowLoop) {
+  ABORT_AUDIO_TEST_IF_NOT(audio_manager_->HasAudioOutputDevices());
 
   uint32_t samples_100_ms = AudioParameters::kAudioCDSampleRate / 10;
-  AudioOutputStream* oas = audio_man->MakeAudioOutputStream(
+  AudioOutputStream* oas = audio_manager_->MakeAudioOutputStream(
       AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, CHANNEL_LAYOUT_MONO,
                       AudioParameters::kAudioCDSampleRate, 16, samples_100_ms),
       std::string());
@@ -281,15 +304,14 @@
 // This test produces actual audio for .5 seconds on the default wave
 // device at 44.1K s/sec. Parameters have been chosen carefully so you should
 // not hear pops or noises while the sound is playing.
-TEST(WinAudioTest, PCMWaveStreamPlay200HzTone44Kss) {
-  scoped_ptr<AudioManager> audio_man(AudioManager::CreateForTesting());
-  if (!audio_man->HasAudioOutputDevices()) {
+TEST_F(WinAudioTest, PCMWaveStreamPlay200HzTone44Kss) {
+  if (!audio_manager_->HasAudioOutputDevices()) {
     LOG(WARNING) << "No output device detected.";
     return;
   }
 
   uint32_t samples_100_ms = AudioParameters::kAudioCDSampleRate / 10;
-  AudioOutputStream* oas = audio_man->MakeAudioOutputStream(
+  AudioOutputStream* oas = audio_manager_->MakeAudioOutputStream(
       AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, CHANNEL_LAYOUT_MONO,
                       AudioParameters::kAudioCDSampleRate, 16, samples_100_ms),
       std::string());
@@ -309,12 +331,11 @@
 // device at 22K s/sec. Parameters have been chosen carefully so you should
 // not hear pops or noises while the sound is playing. The audio also should
 // sound with a lower volume than PCMWaveStreamPlay200HzTone44Kss.
-TEST(WinAudioTest, PCMWaveStreamPlay200HzTone22Kss) {
-  scoped_ptr<AudioManager> audio_man(AudioManager::CreateForTesting());
-  ABORT_AUDIO_TEST_IF_NOT(audio_man->HasAudioOutputDevices());
+TEST_F(WinAudioTest, PCMWaveStreamPlay200HzTone22Kss) {
+  ABORT_AUDIO_TEST_IF_NOT(audio_manager_->HasAudioOutputDevices());
 
   uint32_t samples_100_ms = AudioParameters::kAudioCDSampleRate / 20;
-  AudioOutputStream* oas = audio_man->MakeAudioOutputStream(
+  AudioOutputStream* oas = audio_manager_->MakeAudioOutputStream(
       AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, CHANNEL_LAYOUT_MONO,
                       AudioParameters::kAudioCDSampleRate / 2, 16,
                       samples_100_ms),
@@ -341,9 +362,8 @@
 // Uses a restricted source to play ~2 seconds of audio for about 5 seconds. We
 // try hard to generate situation where the two threads are accessing the
 // object roughly at the same time.
-TEST(WinAudioTest, PushSourceFile16KHz)  {
-  scoped_ptr<AudioManager> audio_man(AudioManager::CreateForTesting());
-  ABORT_AUDIO_TEST_IF_NOT(audio_man->HasAudioOutputDevices());
+TEST_F(WinAudioTest, PushSourceFile16KHz) {
+  ABORT_AUDIO_TEST_IF_NOT(audio_manager_->HasAudioOutputDevices());
 
   static const int kSampleRate = 16000;
   SineWaveAudioSource source(1, 200.0, kSampleRate);
@@ -352,7 +372,7 @@
   // Restrict SineWaveAudioSource to 100ms of samples.
   source.CapSamples(kSamples100ms);
 
-  AudioOutputStream* oas = audio_man->MakeAudioOutputStream(
+  AudioOutputStream* oas = audio_manager_->MakeAudioOutputStream(
       AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, CHANNEL_LAYOUT_MONO,
                       kSampleRate, 16, kSamples100ms),
       std::string());
@@ -381,12 +401,11 @@
 // This test is to make sure an AudioOutputStream can be started after it was
 // stopped. You will here two .5 seconds wave signal separated by 0.5 seconds
 // of silence.
-TEST(WinAudioTest, PCMWaveStreamPlayTwice200HzTone44Kss) {
-  scoped_ptr<AudioManager> audio_man(AudioManager::CreateForTesting());
-  ABORT_AUDIO_TEST_IF_NOT(audio_man->HasAudioOutputDevices());
+TEST_F(WinAudioTest, PCMWaveStreamPlayTwice200HzTone44Kss) {
+  ABORT_AUDIO_TEST_IF_NOT(audio_manager_->HasAudioOutputDevices());
 
   uint32_t samples_100_ms = AudioParameters::kAudioCDSampleRate / 10;
-  AudioOutputStream* oas = audio_man->MakeAudioOutputStream(
+  AudioOutputStream* oas = audio_manager_->MakeAudioOutputStream(
       AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, CHANNEL_LAYOUT_MONO,
                       AudioParameters::kAudioCDSampleRate, 16, samples_100_ms),
       std::string());
@@ -415,21 +434,20 @@
 // With the low latency mode, WASAPI is utilized by default for Vista and
 // higher and Wave is used for XP and lower. It is possible to utilize a
 // smaller buffer size for WASAPI than for Wave.
-TEST(WinAudioTest, PCMWaveStreamPlay200HzToneLowLatency) {
-  scoped_ptr<AudioManager> audio_man(AudioManager::CreateForTesting());
-  ABORT_AUDIO_TEST_IF_NOT(audio_man->HasAudioOutputDevices());
+TEST_F(WinAudioTest, PCMWaveStreamPlay200HzToneLowLatency) {
+  ABORT_AUDIO_TEST_IF_NOT(audio_manager_->HasAudioOutputDevices());
 
   // Use 10 ms buffer size for WASAPI and 50 ms buffer size for Wave.
   // Take the existing native sample rate into account.
-  const AudioParameters params = audio_man->GetDefaultOutputStreamParameters();
+  const AudioParameters params =
+      audio_manager_->GetDefaultOutputStreamParameters();
   int sample_rate = params.sample_rate();
   uint32_t samples_10_ms = sample_rate / 100;
   int n = 1;
   (base::win::GetVersion() <= base::win::VERSION_XP) ? n = 5 : n = 1;
-  AudioOutputStream* oas = audio_man->MakeAudioOutputStream(
+  AudioOutputStream* oas = audio_manager_->MakeAudioOutputStream(
       AudioParameters(AudioParameters::AUDIO_PCM_LOW_LATENCY,
-                      CHANNEL_LAYOUT_MONO, sample_rate,
-                      16, n * samples_10_ms),
+                      CHANNEL_LAYOUT_MONO, sample_rate, 16, n * samples_10_ms),
       std::string());
   ASSERT_TRUE(NULL != oas);
 
@@ -453,12 +471,11 @@
 }
 
 // Check that the pending bytes value is correct what the stream starts.
-TEST(WinAudioTest, PCMWaveStreamPendingBytes) {
-  scoped_ptr<AudioManager> audio_man(AudioManager::CreateForTesting());
-  ABORT_AUDIO_TEST_IF_NOT(audio_man->HasAudioOutputDevices());
+TEST_F(WinAudioTest, PCMWaveStreamPendingBytes) {
+  ABORT_AUDIO_TEST_IF_NOT(audio_manager_->HasAudioOutputDevices());
 
   uint32_t samples_100_ms = AudioParameters::kAudioCDSampleRate / 10;
-  AudioOutputStream* oas = audio_man->MakeAudioOutputStream(
+  AudioOutputStream* oas = audio_manager_->MakeAudioOutputStream(
       AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, CHANNEL_LAYOUT_MONO,
                       AudioParameters::kAudioCDSampleRate, 16, samples_100_ms),
       std::string());
@@ -585,18 +602,16 @@
 // principle of the test still remains and we avoid the additional complexity
 // related to the two different audio-layers for AUDIO_PCM_LOW_LATENCY.
 // In this test you should hear a continuous 200Hz tone for 2 seconds.
-TEST(WinAudioTest, SyncSocketBasic) {
-  scoped_ptr<AudioManager> audio_man(AudioManager::CreateForTesting());
-  ABORT_AUDIO_TEST_IF_NOT(audio_man->HasAudioOutputDevices());
+TEST_F(WinAudioTest, SyncSocketBasic) {
+  ABORT_AUDIO_TEST_IF_NOT(audio_manager_->HasAudioOutputDevices());
 
   static const int sample_rate = AudioParameters::kAudioCDSampleRate;
   static const uint32_t kSamples20ms = sample_rate / 50;
   AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR,
                          CHANNEL_LAYOUT_MONO, sample_rate, 16, kSamples20ms);
 
-
-  AudioOutputStream* oas = audio_man->MakeAudioOutputStream(params,
-      std::string());
+  AudioOutputStream* oas =
+      audio_manager_->MakeAudioOutputStream(params, std::string());
   ASSERT_TRUE(NULL != oas);
 
   ASSERT_TRUE(oas->Open());
diff --git a/media/cast/test/receiver.cc b/media/cast/test/receiver.cc
index d32dd2d0..b452221 100644
--- a/media/cast/test/receiver.cc
+++ b/media/cast/test/receiver.cc
@@ -548,14 +548,15 @@
   base::AtExitManager at_exit;
   base::CommandLine::Init(argc, argv);
   InitLogging(logging::LoggingSettings());
+  base::MessageLoop message_loop;
 
   scoped_refptr<media::cast::CastEnvironment> cast_environment(
       new media::cast::StandaloneCastEnvironment);
 
   // Start up Chromium audio system.
-  media::FakeAudioLogFactory fake_audio_log_factory_;
-  const scoped_ptr<media::AudioManager> audio_manager(
-      media::AudioManager::Create(&fake_audio_log_factory_));
+  const media::ScopedAudioManagerPtr audio_manager(
+      media::AudioManager::CreateForTesting(
+          base::ThreadTaskRunnerHandle::Get()));
   CHECK(media::AudioManager::Get());
 
   media::cast::FrameReceiverConfig audio_config =
@@ -600,7 +601,7 @@
                                   window_height);
   player.Start();
 
-  base::MessageLoop().Run();  // Run forever (i.e., until SIGTERM).
+  message_loop.Run();  // Run forever (i.e., until SIGTERM).
   NOTREACHED();
   return 0;
 }
diff --git a/media/mojo/services/mojo_media_application.cc b/media/mojo/services/mojo_media_application.cc
index 76fd23a..5ef80e5 100644
--- a/media/mojo/services/mojo_media_application.cc
+++ b/media/mojo/services/mojo_media_application.cc
@@ -37,6 +37,11 @@
   return true;
 }
 
+bool MojoMediaApplication::ShellConnectionLost() {
+  mojo_media_client_->WillQuit();
+  return true;
+}
+
 void MojoMediaApplication::Create(
     shell::Connection* connection,
     mojo::InterfaceRequest<interfaces::ServiceFactory> request) {
diff --git a/media/mojo/services/mojo_media_application.h b/media/mojo/services/mojo_media_application.h
index 373c221..9682d01 100644
--- a/media/mojo/services/mojo_media_application.h
+++ b/media/mojo/services/mojo_media_application.h
@@ -36,6 +36,7 @@
                   const shell::Identity& identity,
                   uint32_t id) final;
   bool AcceptConnection(shell::Connection* connection) final;
+  bool ShellConnectionLost() final;
 
   // shell::InterfaceFactory<interfaces::ServiceFactory> implementation.
   void Create(shell::Connection* connection,
diff --git a/media/mojo/services/mojo_media_client.cc b/media/mojo/services/mojo_media_client.cc
index 2d81841b..56d16b0 100644
--- a/media/mojo/services/mojo_media_client.cc
+++ b/media/mojo/services/mojo_media_client.cc
@@ -12,6 +12,8 @@
 
 void MojoMediaClient::Initialize() {}
 
+void MojoMediaClient::WillQuit() {}
+
 std::unique_ptr<AudioDecoder> MojoMediaClient::CreateAudioDecoder(
     scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
   return nullptr;
diff --git a/media/mojo/services/mojo_media_client.h b/media/mojo/services/mojo_media_client.h
index eb923e2..d64c06c 100644
--- a/media/mojo/services/mojo_media_client.h
+++ b/media/mojo/services/mojo_media_client.h
@@ -32,6 +32,10 @@
 
   // Called exactly once before any other method.
   virtual void Initialize();
+  // Called before the host application is scheduled to quit.
+  // The application message loop is still valid at this point, so all clean
+  // up tasks requiring the message loop must be completed before returning.
+  virtual void WillQuit();
 
   virtual std::unique_ptr<AudioDecoder> CreateAudioDecoder(
       scoped_refptr<base::SingleThreadTaskRunner> task_runner);
diff --git a/media/mojo/services/test_mojo_media_client.cc b/media/mojo/services/test_mojo_media_client.cc
index 8dbd843..6388e530 100644
--- a/media/mojo/services/test_mojo_media_client.cc
+++ b/media/mojo/services/test_mojo_media_client.cc
@@ -5,6 +5,8 @@
 #include "media/mojo/services/test_mojo_media_client.h"
 
 #include "base/memory/ptr_util.h"
+#include "base/run_loop.h"
+#include "base/thread_task_runner_handle.h"
 #include "media/audio/audio_manager_base.h"
 #include "media/audio/audio_output_stream_sink.h"
 #include "media/base/audio_hardware_config.h"
@@ -25,12 +27,14 @@
   // TODO(dalecurtis): We should find a single owner per process for the audio
   // manager or make it a lazy instance.  It's not safe to call Get()/Create()
   // across multiple threads...
-  //
-  // TODO(dalecurtis): Eventually we'll want something other than a fake audio
-  // log factory here too.  We should probably at least DVLOG() such info.
   AudioManager* audio_manager = AudioManager::Get();
-  if (!audio_manager)
-    audio_manager = media::AudioManager::Create(&fake_audio_log_factory_);
+  if (!audio_manager) {
+    audio_manager_ = media::AudioManager::CreateForTesting(
+        base::ThreadTaskRunnerHandle::Get());
+    audio_manager = audio_manager_.get();
+    // Flush the message loop to ensure that the audio manager is initialized.
+    base::RunLoop().RunUntilIdle();
+  }
 
   audio_hardware_config_.reset(new AudioHardwareConfig(
       audio_manager->GetInputStreamParameters(
@@ -38,6 +42,15 @@
       audio_manager->GetDefaultOutputStreamParameters()));
 }
 
+void TestMojoMediaClient::WillQuit() {
+  DVLOG(1) << __FUNCTION__;
+  // AudioManager destructor requires MessageLoop.
+  // Destroy it before the message loop goes away.
+  audio_manager_.reset();
+  // Flush the message loop to ensure that the audio manager is destroyed.
+  base::RunLoop().RunUntilIdle();
+}
+
 std::unique_ptr<RendererFactory> TestMojoMediaClient::CreateRendererFactory(
     const scoped_refptr<MediaLog>& media_log) {
   DVLOG(1) << __FUNCTION__;
diff --git a/media/mojo/services/test_mojo_media_client.h b/media/mojo/services/test_mojo_media_client.h
index 8bf795cd..5494e365 100644
--- a/media/mojo/services/test_mojo_media_client.h
+++ b/media/mojo/services/test_mojo_media_client.h
@@ -9,7 +9,7 @@
 
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
-#include "media/audio/fake_audio_log_factory.h"
+#include "media/audio/audio_manager.h"
 #include "media/mojo/services/mojo_media_client.h"
 
 namespace media {
@@ -26,6 +26,7 @@
 
   // MojoMediaClient implementation.
   void Initialize() final;
+  void WillQuit() final;
   std::unique_ptr<RendererFactory> CreateRendererFactory(
       const scoped_refptr<MediaLog>& media_log) final;
   AudioRendererSink* CreateAudioRendererSink() final;
@@ -35,7 +36,7 @@
       shell::mojom::InterfaceProvider* /* interface_provider */) final;
 
  private:
-  FakeAudioLogFactory fake_audio_log_factory_;
+  ScopedAudioManagerPtr audio_manager_;
   std::unique_ptr<AudioHardwareConfig> audio_hardware_config_;
   scoped_refptr<AudioRendererSink> audio_renderer_sink_;
   std::unique_ptr<VideoRendererSink> video_renderer_sink_;