1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "media/audio/audio_output_proxy.h" 6 7 #include "base/logging.h" 8 #include "base/message_loop/message_loop.h" 9 #include "media/audio/audio_manager.h" 10 #include "media/audio/audio_output_dispatcher.h" 11 12 namespace media { 13 14 AudioOutputProxy::AudioOutputProxy(AudioOutputDispatcher* dispatcher) 15 : dispatcher_(dispatcher), 16 state_(kCreated), 17 volume_(1.0) { 18 } 19 20 AudioOutputProxy::~AudioOutputProxy() { 21 DCHECK(CalledOnValidThread()); 22 DCHECK(state_ == kCreated || state_ == kClosed) << "State is: " << state_; 23 } 24 25 bool AudioOutputProxy::Open() { 26 DCHECK(CalledOnValidThread()); 27 DCHECK_EQ(state_, kCreated); 28 29 if (!dispatcher_->OpenStream()) { 30 state_ = kOpenError; 31 return false; 32 } 33 34 state_ = kOpened; 35 return true; 36 } 37 38 void AudioOutputProxy::Start(AudioSourceCallback* callback) { 39 DCHECK(CalledOnValidThread()); 40 41 // We need to support both states since the callback may not handle OnError() 42 // immediately (or at all). It's also possible for subsequent StartStream() 43 // calls to succeed after failing, so we allow it to be called again. 44 DCHECK(state_ == kOpened || state_ == kStartError); 45 46 if (!dispatcher_->StartStream(callback, this)) { 47 state_ = kStartError; 48 callback->OnError(this); 49 return; 50 } 51 state_ = kPlaying; 52 } 53 54 void AudioOutputProxy::Stop() { 55 DCHECK(CalledOnValidThread()); 56 if (state_ != kPlaying) 57 return; 58 59 dispatcher_->StopStream(this); 60 state_ = kOpened; 61 } 62 63 void AudioOutputProxy::SetVolume(double volume) { 64 DCHECK(CalledOnValidThread()); 65 volume_ = volume; 66 dispatcher_->StreamVolumeSet(this, volume); 67 } 68 69 void AudioOutputProxy::GetVolume(double* volume) { 70 DCHECK(CalledOnValidThread()); 71 *volume = volume_; 72 } 73 74 void AudioOutputProxy::Close() { 75 DCHECK(CalledOnValidThread()); 76 DCHECK(state_ == kCreated || state_ == kOpenError || state_ == kOpened || 77 state_ == kStartError); 78 79 // kStartError means OpenStream() succeeded and the stream must be closed 80 // before destruction. 81 if (state_ != kCreated && state_ != kOpenError) 82 dispatcher_->CloseStream(this); 83 84 state_ = kClosed; 85 86 // Delete the object now like is done in the Close() implementation of 87 // physical stream objects. If we delete the object via DeleteSoon, we 88 // unnecessarily complicate the Shutdown procedure of the 89 // dispatcher+audio manager. 90 delete this; 91 } 92 93 } // namespace media 94