blob: c678645eae247eb460ae38f35e7c87438fb46b90 [file] [log] [blame]
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "media/audio/sounds/sounds_manager.h"
#include <vector>
#include "base/logging.h"
#include "base/memory/ref_counted.h"
#include "media/audio/audio_manager.h"
#include "media/audio/sounds/audio_stream_handler.h"
namespace media {
namespace {
SoundsManager* g_instance = NULL;
bool g_initialized_for_testing = false;
// SoundsManagerImpl ---------------------------------------------------
class SoundsManagerImpl : public SoundsManager {
public:
SoundsManagerImpl() {}
~SoundsManagerImpl() override { DCHECK(CalledOnValidThread()); }
// SoundsManager implementation:
bool Initialize(SoundKey key, const base::StringPiece& data) override;
bool Play(SoundKey key) override;
bool Stop(SoundKey key) override;
base::TimeDelta GetDuration(SoundKey key) override;
private:
AudioStreamHandler* GetHandler(SoundKey key);
// There's only a handful of sounds, so a vector is sufficient.
struct StreamEntry {
SoundKey key;
std::unique_ptr<AudioStreamHandler> handler;
};
std::vector<StreamEntry> handlers_;
DISALLOW_COPY_AND_ASSIGN(SoundsManagerImpl);
};
bool SoundsManagerImpl::Initialize(SoundKey key,
const base::StringPiece& data) {
if (AudioStreamHandler* handler = GetHandler(key)) {
DCHECK(handler->IsInitialized());
return true;
}
std::unique_ptr<AudioStreamHandler> handler(new AudioStreamHandler(data));
if (!handler->IsInitialized()) {
LOG(WARNING) << "Can't initialize AudioStreamHandler for key=" << key;
return false;
}
handlers_.push_back({key, std::move(handler)});
return true;
}
bool SoundsManagerImpl::Play(SoundKey key) {
DCHECK(CalledOnValidThread());
AudioStreamHandler* handler = GetHandler(key);
return handler && handler->Play();
}
bool SoundsManagerImpl::Stop(SoundKey key) {
DCHECK(CalledOnValidThread());
AudioStreamHandler* handler = GetHandler(key);
if (!handler)
return false;
handler->Stop();
return true;
}
base::TimeDelta SoundsManagerImpl::GetDuration(SoundKey key) {
DCHECK(CalledOnValidThread());
AudioStreamHandler* handler = GetHandler(key);
return !handler ? base::TimeDelta() : handler->duration();
}
AudioStreamHandler* SoundsManagerImpl::GetHandler(SoundKey key) {
for (auto& entry : handlers_) {
if (entry.key == key)
return entry.handler.get();
}
return nullptr;
}
} // namespace
SoundsManager::SoundsManager() {}
SoundsManager::~SoundsManager() { DCHECK(CalledOnValidThread()); }
// static
void SoundsManager::Create() {
CHECK(!g_instance || g_initialized_for_testing)
<< "SoundsManager::Create() is called twice";
if (g_initialized_for_testing)
return;
g_instance = new SoundsManagerImpl();
}
// static
void SoundsManager::Shutdown() {
CHECK(g_instance) << "SoundsManager::Shutdown() is called "
<< "without previous call to Create()";
delete g_instance;
g_instance = NULL;
}
// static
SoundsManager* SoundsManager::Get() {
CHECK(g_instance) << "SoundsManager::Get() is called before Create()";
return g_instance;
}
// static
void SoundsManager::InitializeForTesting(SoundsManager* manager) {
CHECK(!g_instance) << "SoundsManager is already initialized.";
CHECK(manager);
g_instance = manager;
g_initialized_for_testing = true;
}
} // namespace media