sounds_manager.cc revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
1// Copyright 2013 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/sounds/sounds_manager.h"
6
7#include "base/command_line.h"
8#include "base/compiler_specific.h"
9#include "base/logging.h"
10#include "base/memory/linked_ptr.h"
11#include "base/memory/ref_counted.h"
12#include "base/single_thread_task_runner.h"
13#include "media/audio/audio_manager.h"
14#include "media/audio/sounds/audio_stream_handler.h"
15#include "media/base/media_switches.h"
16
17namespace media {
18
19namespace {
20
21SoundsManager* g_instance = NULL;
22bool g_initialized_for_testing = false;
23
24// SoundsManagerImpl ---------------------------------------------------
25
26class SoundsManagerImpl : public SoundsManager {
27 public:
28  SoundsManagerImpl();
29  virtual ~SoundsManagerImpl();
30
31  // SoundsManager implementation:
32  virtual bool Initialize(SoundKey key,
33                          const base::StringPiece& data) OVERRIDE;
34  virtual bool Play(SoundKey key) OVERRIDE;
35  virtual base::TimeDelta GetDuration(SoundKey key) OVERRIDE;
36
37 private:
38  base::hash_map<SoundKey, linked_ptr<AudioStreamHandler> > handlers_;
39  scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
40
41  DISALLOW_COPY_AND_ASSIGN(SoundsManagerImpl);
42};
43
44SoundsManagerImpl::SoundsManagerImpl()
45    : task_runner_(AudioManager::Get()->GetTaskRunner()) {
46}
47
48SoundsManagerImpl::~SoundsManagerImpl() { DCHECK(CalledOnValidThread()); }
49
50bool SoundsManagerImpl::Initialize(SoundKey key,
51                                   const base::StringPiece& data) {
52  if (handlers_.find(key) != handlers_.end() && handlers_[key]->IsInitialized())
53    return true;
54  linked_ptr<AudioStreamHandler> handler(new AudioStreamHandler(data));
55  if (!handler->IsInitialized()) {
56    LOG(WARNING) << "Can't initialize AudioStreamHandler for key=" << key;
57    return false;
58  }
59  handlers_[key] = handler;
60  return true;
61}
62
63bool SoundsManagerImpl::Play(SoundKey key) {
64  DCHECK(CalledOnValidThread());
65  if (handlers_.find(key) == handlers_.end() ||
66      !handlers_[key]->IsInitialized()) {
67    return false;
68  }
69  return handlers_[key]->Play();
70}
71
72base::TimeDelta SoundsManagerImpl::GetDuration(SoundKey key) {
73  DCHECK(CalledOnValidThread());
74  if (handlers_.find(key) == handlers_.end() ||
75      !handlers_[key]->IsInitialized()) {
76    return base::TimeDelta();
77  }
78  const WavAudioHandler& wav_audio = handlers_[key]->wav_audio_handler();
79  return wav_audio.params().GetBufferDuration();
80}
81
82// SoundsManagerStub ---------------------------------------------------
83
84class SoundsManagerStub : public SoundsManager {
85 public:
86  SoundsManagerStub();
87  virtual ~SoundsManagerStub();
88
89  // SoundsManager implementation:
90  virtual bool Initialize(SoundKey key,
91                          const base::StringPiece& data) OVERRIDE;
92  virtual bool Play(SoundKey key) OVERRIDE;
93  virtual base::TimeDelta GetDuration(SoundKey key) OVERRIDE;
94
95 private:
96  DISALLOW_COPY_AND_ASSIGN(SoundsManagerStub);
97};
98
99SoundsManagerStub::SoundsManagerStub() {}
100
101SoundsManagerStub::~SoundsManagerStub() { DCHECK(CalledOnValidThread()); }
102
103bool SoundsManagerStub::Initialize(SoundKey /* key */,
104                                   const base::StringPiece& /* data */) {
105  DCHECK(CalledOnValidThread());
106  return false;
107}
108
109bool SoundsManagerStub::Play(SoundKey /* key */) {
110  DCHECK(CalledOnValidThread());
111  return false;
112}
113
114base::TimeDelta SoundsManagerStub::GetDuration(SoundKey /* key */) {
115  DCHECK(CalledOnValidThread());
116  return base::TimeDelta();
117}
118
119}  // namespace
120
121SoundsManager::SoundsManager() {}
122
123SoundsManager::~SoundsManager() { DCHECK(CalledOnValidThread()); }
124
125// static
126void SoundsManager::Create() {
127  CHECK(!g_instance || g_initialized_for_testing)
128      << "SoundsManager::Create() is called twice";
129  if (g_initialized_for_testing)
130    return;
131
132  const bool enabled = !CommandLine::ForCurrentProcess()->HasSwitch(
133                            ::switches::kDisableSystemSoundsManager);
134  if (enabled)
135    g_instance = new SoundsManagerImpl();
136  else
137    g_instance = new SoundsManagerStub();
138}
139
140// static
141void SoundsManager::Shutdown() {
142  CHECK(g_instance) << "SoundsManager::Shutdown() is called "
143                    << "without previous call to Create()";
144  delete g_instance;
145  g_instance = NULL;
146}
147
148// static
149SoundsManager* SoundsManager::Get() {
150  CHECK(g_instance) << "SoundsManager::Get() is called before Create()";
151  return g_instance;
152}
153
154// static
155void SoundsManager::InitializeForTesting(SoundsManager* manager) {
156  CHECK(!g_instance) << "SoundsManager is already initialized.";
157  CHECK(manager);
158  g_instance = manager;
159  g_initialized_for_testing = true;
160}
161
162}  // namespace media
163