15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/basictypes.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/environment.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/ref_counted.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/scoped_ptr.h"
11ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "base/message_loop/message_loop.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/synchronization/waitable_event.h"
131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "media/audio/audio_manager_base.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/audio/audio_output_controller.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "media/audio/audio_parameters.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "media/base/audio_bus.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::_;
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::AtLeast;
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::DoAll;
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using ::testing::Invoke;
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::NotNull;
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::Return;
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace media {
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kSampleRate = AudioParameters::kAudioCDSampleRate;
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kBitsPerSample = 16;
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const ChannelLayout kChannelLayout = CHANNEL_LAYOUT_STEREO;
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static const int kSamplesPerPacket = kSampleRate / 100;
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static const double kTestVolume = 0.25;
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MockAudioOutputControllerEventHandler
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : public AudioOutputController::EventHandler {
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockAudioOutputControllerEventHandler() {}
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MOCK_METHOD0(OnCreated, void());
41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MOCK_METHOD0(OnPlaying, void());
42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MOCK_METHOD0(OnPaused, void());
43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MOCK_METHOD0(OnError, void());
44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MOCK_METHOD2(OnDeviceChange, void(int new_buffer_size, int new_sample_rate));
45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(MockAudioOutputControllerEventHandler);
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MockAudioOutputControllerSyncReader
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : public AudioOutputController::SyncReader {
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockAudioOutputControllerSyncReader() {}
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MOCK_METHOD1(UpdatePendingBytes, void(uint32 bytes));
56cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  MOCK_METHOD1(Read, void(AudioBus* dest));
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MOCK_METHOD0(Close, void());
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(MockAudioOutputControllerSyncReader);
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class MockAudioOutputStream : public AudioOutputStream {
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MOCK_METHOD0(Open, bool());
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MOCK_METHOD1(Start, void(AudioSourceCallback* callback));
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MOCK_METHOD0(Stop, void());
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MOCK_METHOD1(SetVolume, void(double volume));
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MOCK_METHOD1(GetVolume, void(double* volume));
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MOCK_METHOD0(Close, void());
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Set/get the callback passed to Start().
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AudioSourceCallback* callback() const { return callback_; }
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void SetCallback(AudioSourceCallback* asc) { callback_ = asc; }
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AudioSourceCallback* callback_;
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ACTION_P(SignalEvent, event) {
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  event->Signal();
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static const float kBufferNonZeroData = 1.0f;
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ACTION(PopulateBuffer) {
86cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  arg0->Zero();
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Note: To confirm the buffer will be populated in these tests, it's
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // sufficient that only the first float in channel 0 is set to the value.
89cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  arg0->channel(0)[0] = kBufferNonZeroData;
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class AudioOutputControllerTest : public testing::Test {
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AudioOutputControllerTest()
95a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      : audio_manager_(AudioManager::CreateForTesting()),
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        create_event_(false, false),
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        play_event_(false, false),
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        read_event_(false, false),
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        pause_event_(false, false) {
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~AudioOutputControllerTest() {
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void Create(int samples_per_packet) {
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_FALSE(create_event_.IsSignaled());
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_FALSE(play_event_.IsSignaled());
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_FALSE(read_event_.IsSignaled());
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_FALSE(pause_event_.IsSignaled());
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    params_ = AudioParameters(
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        AudioParameters::AUDIO_FAKE, kChannelLayout,
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        kSampleRate, kBitsPerSample, samples_per_packet);
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (params_.IsValid()) {
117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      EXPECT_CALL(mock_event_handler_, OnCreated())
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          .WillOnce(SignalEvent(&create_event_));
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    controller_ = AudioOutputController::Create(
122868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        audio_manager_.get(), &mock_event_handler_, params_, std::string(),
1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        &mock_sync_reader_);
124868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (controller_.get())
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      controller_->SetVolume(kTestVolume);
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
127868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    EXPECT_EQ(params_.IsValid(), controller_.get() != NULL);
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void Play() {
131a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Expect the event handler to receive one OnPlaying() call.
132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_CALL(mock_event_handler_, OnPlaying())
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        .WillOnce(SignalEvent(&play_event_));
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // During playback, the mock pretends to provide audio data rendered and
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // sent from the render process.
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_CALL(mock_sync_reader_, UpdatePendingBytes(_))
138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        .Times(AtLeast(1));
139cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    EXPECT_CALL(mock_sync_reader_, Read(_))
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        .WillRepeatedly(DoAll(PopulateBuffer(),
1411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                              SignalEvent(&read_event_)));
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    controller_->Play();
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void Pause() {
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Expect the event handler to receive one OnPaused() call.
147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_CALL(mock_event_handler_, OnPaused())
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        .WillOnce(SignalEvent(&pause_event_));
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    controller_->Pause();
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void ChangeDevice() {
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Expect the event handler to receive one OnPaying() call and no OnPaused()
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // call.
156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_CALL(mock_event_handler_, OnPlaying())
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        .WillOnce(SignalEvent(&play_event_));
158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_CALL(mock_event_handler_, OnPaused())
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        .Times(0);
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Simulate a device change event to AudioOutputController from the
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // AudioManager.
1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    audio_manager_->GetTaskRunner()->PostTask(
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        FROM_HERE,
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::Bind(&AudioOutputController::OnDeviceChange, controller_));
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void Divert(bool was_playing, int num_times_to_be_started) {
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (was_playing) {
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // Expect the handler to receive one OnPlaying() call as a result of the
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // stream switching.
172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      EXPECT_CALL(mock_event_handler_, OnPlaying())
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          .WillOnce(SignalEvent(&play_event_));
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_CALL(mock_stream_, Open())
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        .WillOnce(Return(true));
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_CALL(mock_stream_, SetVolume(kTestVolume));
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (num_times_to_be_started > 0) {
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_CALL(mock_stream_, Start(NotNull()))
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          .Times(num_times_to_be_started)
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          .WillRepeatedly(
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              Invoke(&mock_stream_, &MockAudioOutputStream::SetCallback));
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_CALL(mock_stream_, Stop())
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          .Times(num_times_to_be_started);
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    controller_->StartDiverting(&mock_stream_);
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void ReadDivertedAudioData() {
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<AudioBus> dest = AudioBus::Create(params_);
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_TRUE(!!mock_stream_.callback());
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const int frames_read =
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        mock_stream_.callback()->OnMoreData(dest.get(), AudioBuffersState());
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_LT(0, frames_read);
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(kBufferNonZeroData, dest->channel(0)[0]);
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void Revert(bool was_playing) {
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (was_playing) {
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // Expect the handler to receive one OnPlaying() call as a result of the
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // stream switching back.
204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      EXPECT_CALL(mock_event_handler_, OnPlaying())
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          .WillOnce(SignalEvent(&play_event_));
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_CALL(mock_stream_, Close());
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    controller_->StopDiverting();
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  void SwitchDevice(bool diverting) {
2141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    if (!diverting) {
2151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      // Expect the current stream to close and a new stream to start
2161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      // playing if not diverting. When diverting, nothing happens
2171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      // until diverting is stopped.
2181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      EXPECT_CALL(mock_event_handler_, OnPlaying())
2191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          .WillOnce(SignalEvent(&play_event_));
2201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    }
2211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    controller_->SwitchOutputDevice(AudioManagerBase::kDefaultDeviceName,
2231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                    base::Bind(&base::DoNothing));
2241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
2251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void Close() {
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_CALL(mock_sync_reader_, Close());
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    controller_->Close(base::MessageLoop::QuitClosure());
230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    base::MessageLoop::current()->Run();
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // These help make test sequences more readable.
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void DivertNeverPlaying() { Divert(false, 0); }
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void DivertWillEventuallyBeTwicePlayed() { Divert(false, 2); }
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void DivertWhilePlaying() { Divert(true, 1); }
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void RevertWasNotPlaying() { Revert(false); }
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void RevertWhilePlaying() { Revert(true); }
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // These synchronize the main thread with key events taking place on other
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // threads.
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void WaitForCreate() { create_event_.Wait(); }
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void WaitForPlay() { play_event_.Wait(); }
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void WaitForReads() {
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Note: Arbitrarily chosen, but more iterations causes tests to take
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // significantly more time.
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    static const int kNumIterations = 3;
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (int i = 0; i < kNumIterations; ++i) {
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      read_event_.Wait();
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void WaitForPause() { pause_event_.Wait(); }
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
255c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::MessageLoopForIO message_loop_;
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<AudioManager> audio_manager_;
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockAudioOutputControllerEventHandler mock_event_handler_;
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockAudioOutputControllerSyncReader mock_sync_reader_;
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockAudioOutputStream mock_stream_;
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::WaitableEvent create_event_;
2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::WaitableEvent play_event_;
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::WaitableEvent read_event_;
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::WaitableEvent pause_event_;
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AudioParameters params_;
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<AudioOutputController> controller_;
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(AudioOutputControllerTest);
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AudioOutputControllerTest, CreateAndClose) {
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Create(kSamplesPerPacket);
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Close();
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(AudioOutputControllerTest, HardwareBufferTooLarge) {
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Create(kSamplesPerPacket * 1000);
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(AudioOutputControllerTest, PlayAndClose) {
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Create(kSamplesPerPacket);
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WaitForCreate();
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Play();
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WaitForPlay();
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WaitForReads();
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Close();
2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(AudioOutputControllerTest, PlayPauseClose) {
2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Create(kSamplesPerPacket);
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WaitForCreate();
2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Play();
2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WaitForPlay();
2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WaitForReads();
2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Pause();
2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WaitForPause();
2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Close();
2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(AudioOutputControllerTest, PlayPausePlayClose) {
3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Create(kSamplesPerPacket);
3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WaitForCreate();
3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Play();
3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WaitForPlay();
3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WaitForReads();
3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Pause();
3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WaitForPause();
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Play();
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WaitForPlay();
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Close();
3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(AudioOutputControllerTest, PlayDeviceChangeClose) {
3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Create(kSamplesPerPacket);
3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WaitForCreate();
3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Play();
3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WaitForPlay();
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WaitForReads();
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ChangeDevice();
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WaitForPlay();
3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WaitForReads();
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Close();
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)TEST_F(AudioOutputControllerTest, PlaySwitchDeviceClose) {
3251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  Create(kSamplesPerPacket);
3261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  WaitForCreate();
3271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  Play();
3281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  WaitForPlay();
3291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  WaitForReads();
3301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  SwitchDevice(false);
3311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  WaitForPlay();
3321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  WaitForReads();
3331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  Close();
3341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
3351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(AudioOutputControllerTest, PlayDivertRevertClose) {
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Create(kSamplesPerPacket);
3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WaitForCreate();
3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Play();
3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WaitForPlay();
3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WaitForReads();
3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DivertWhilePlaying();
3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WaitForPlay();
3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ReadDivertedAudioData();
3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RevertWhilePlaying();
3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WaitForPlay();
3471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  WaitForReads();
3481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  Close();
3491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
3501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
3511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)TEST_F(AudioOutputControllerTest, PlayDivertSwitchDeviceRevertClose) {
3521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  Create(kSamplesPerPacket);
3531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  WaitForCreate();
3541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  Play();
3551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  WaitForPlay();
3561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  WaitForReads();
3571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DivertWhilePlaying();
3581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  WaitForPlay();
3591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  SwitchDevice(true);
3601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ReadDivertedAudioData();
3611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  RevertWhilePlaying();
3621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  WaitForPlay();
3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WaitForReads();
3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Close();
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(AudioOutputControllerTest, PlayDivertRevertDivertRevertClose) {
3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Create(kSamplesPerPacket);
3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WaitForCreate();
3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Play();
3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WaitForPlay();
3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WaitForReads();
3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DivertWhilePlaying();
3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WaitForPlay();
3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ReadDivertedAudioData();
3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RevertWhilePlaying();
3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WaitForPlay();
3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WaitForReads();
3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DivertWhilePlaying();
3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WaitForPlay();
3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ReadDivertedAudioData();
3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RevertWhilePlaying();
3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WaitForPlay();
3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WaitForReads();
3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Close();
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(AudioOutputControllerTest, DivertPlayPausePlayRevertClose) {
3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Create(kSamplesPerPacket);
3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WaitForCreate();
3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DivertWillEventuallyBeTwicePlayed();
3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Play();
3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WaitForPlay();
3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ReadDivertedAudioData();
3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Pause();
3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WaitForPause();
3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Play();
3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WaitForPlay();
3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ReadDivertedAudioData();
4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RevertWhilePlaying();
4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WaitForPlay();
4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WaitForReads();
4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Close();
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(AudioOutputControllerTest, DivertRevertClose) {
4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Create(kSamplesPerPacket);
4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WaitForCreate();
4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DivertNeverPlaying();
4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RevertWasNotPlaying();
4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Close();
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace media
415