Commit 3ecaffe9 authored by chun.gao@intel.com's avatar chun.gao@intel.com

Eliminate the dependence of tts extension API form tts_controller.cc

This is the first patch to move TTS implementation from browser layer
to content. To move TTS to conent, the direct dependence of browser
compoent should be eliminated from TTS classes first.

BUG=347045
R=tommi@chromium.org, dmazzoni@chromium.org, sky@chromium.org

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

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@282813 0039d316-1c4b-4281-b951-d872f2087c98
parent a1f1a940
......@@ -126,6 +126,7 @@ Francois Kritzinger <francoisk777@gmail.com>
Frédéric Wang <fred.wang@free.fr>
Gaetano Mendola <mendola@gmail.com>
Gajendra Singh <wxjg68@motorola.com>
Gao Chun <chun.gao@intel.com>
Gao Chun <gaochun.dev@gmail.com>
George Liaskos <geo.liaskos@gmail.com>
Giuseppe Iuculano <giuseppe@iuculano.it>
......
......@@ -71,6 +71,8 @@
#include "chrome/browser/search_engines/search_provider_install_state_message_filter.h"
#include "chrome/browser/signin/principals_message_filter.h"
#include "chrome/browser/speech/chrome_speech_recognition_manager_delegate.h"
#include "chrome/browser/speech/extension_api/tts_engine_extension_api.h"
#include "chrome/browser/speech/tts_controller.h"
#include "chrome/browser/speech/tts_message_filter.h"
#include "chrome/browser/ssl/ssl_add_certificate.h"
#include "chrome/browser/ssl/ssl_blocking_page.h"
......@@ -662,6 +664,11 @@ ChromeContentBrowserClient::ChromeContentBrowserClient()
permissions_policy_delegate_.reset(
new extensions::BrowserPermissionsPolicyDelegate());
#if !defined(OS_ANDROID)
TtsExtensionEngine* tts_extension_engine = TtsExtensionEngine::GetInstance();
TtsController::GetInstance()->SetTtsEngineDelegate(tts_extension_engine);
#endif
}
ChromeContentBrowserClient::~ChromeContentBrowserClient() {
......
......@@ -62,7 +62,12 @@ void WarnIfMissingPauseOrResumeListener(
} // namespace
void GetExtensionVoices(Profile* profile, std::vector<VoiceData>* out_voices) {
TtsExtensionEngine* TtsExtensionEngine::GetInstance() {
return Singleton<TtsExtensionEngine>::get();
}
void TtsExtensionEngine::GetVoices(Profile* profile,
std::vector<VoiceData>* out_voices) {
EventRouter* event_router = EventRouter::Get(profile);
DCHECK(event_router);
......@@ -127,7 +132,8 @@ void GetExtensionVoices(Profile* profile, std::vector<VoiceData>* out_voices) {
}
}
void ExtensionTtsEngineSpeak(Utterance* utterance, const VoiceData& voice) {
void TtsExtensionEngine::Speak(Utterance* utterance,
const VoiceData& voice) {
// See if the engine supports the "end" event; if so, we can keep the
// utterance around and track it. If not, we're finished with this
// utterance now.
......@@ -171,7 +177,7 @@ void ExtensionTtsEngineSpeak(Utterance* utterance, const VoiceData& voice) {
->DispatchEventToExtension(utterance->extension_id(), event.Pass());
}
void ExtensionTtsEngineStop(Utterance* utterance) {
void TtsExtensionEngine::Stop(Utterance* utterance) {
scoped_ptr<base::ListValue> args(new base::ListValue());
scoped_ptr<extensions::Event> event(new extensions::Event(
tts_engine_events::kOnStop, args.Pass()));
......@@ -180,7 +186,7 @@ void ExtensionTtsEngineStop(Utterance* utterance) {
->DispatchEventToExtension(utterance->extension_id(), event.Pass());
}
void ExtensionTtsEnginePause(Utterance* utterance) {
void TtsExtensionEngine::Pause(Utterance* utterance) {
scoped_ptr<base::ListValue> args(new base::ListValue());
scoped_ptr<extensions::Event> event(new extensions::Event(
tts_engine_events::kOnPause, args.Pass()));
......@@ -192,7 +198,7 @@ void ExtensionTtsEnginePause(Utterance* utterance) {
WarnIfMissingPauseOrResumeListener(profile, event_router, id);
}
void ExtensionTtsEngineResume(Utterance* utterance) {
void TtsExtensionEngine::Resume(Utterance* utterance) {
scoped_ptr<base::ListValue> args(new base::ListValue());
scoped_ptr<extensions::Event> event(new extensions::Event(
tts_engine_events::kOnResume, args.Pass()));
......
......@@ -28,32 +28,19 @@ extern const char kOnPause[];
extern const char kOnResume[];
}
// Return a list of all available voices registered by extensions.
void GetExtensionVoices(Profile* profile, std::vector<VoiceData>* out_voices);
// Find the first extension with a tts_voices in its
// manifest that matches the speech parameters of this utterance.
// If found, store a pointer to the extension in |matching_extension| and
// the index of the voice within the extension in |voice_index| and
// return true.
bool GetMatchingExtensionVoice(Utterance* utterance,
const extensions::Extension** matching_extension,
size_t* voice_index);
// Speak the given utterance by sending an event to the given TTS engine
// extension voice.
void ExtensionTtsEngineSpeak(Utterance* utterance,
const VoiceData& voice);
// Stop speaking the given utterance by sending an event to the extension
// associated with this utterance.
void ExtensionTtsEngineStop(Utterance* utterance);
// Pause in the middle of speaking this utterance.
void ExtensionTtsEnginePause(Utterance* utterance);
// Resume speaking this utterance.
void ExtensionTtsEngineResume(Utterance* utterance);
// TtsEngineDelegate implementation used by TtsController.
class TtsExtensionEngine : public TtsEngineDelegate {
public:
static TtsExtensionEngine* GetInstance();
// Overridden from TtsEngineDelegate:
virtual void GetVoices(Profile* profile,
std::vector<VoiceData>* out_voices) OVERRIDE;
virtual void Speak(Utterance* utterance, const VoiceData& voice) OVERRIDE;
virtual void Stop(Utterance* utterance) OVERRIDE;
virtual void Pause(Utterance* utterance) OVERRIDE;
virtual void Resume(Utterance* utterance) OVERRIDE;
};
// Hidden/internal extension function used to allow TTS engine extensions
// to send events back to the client that's calling tts.speak().
......
......@@ -10,13 +10,7 @@
#include "base/float_util.h"
#include "base/values.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/speech/extension_api/tts_engine_extension_api.h"
#include "chrome/browser/speech/extension_api/tts_extension_api.h"
#include "chrome/browser/speech/tts_platform.h"
#include "chrome/common/extensions/api/speech/tts_engine_manifest_handler.h"
#include "extensions/browser/extension_system.h"
#include "extensions/common/extension.h"
namespace {
// A value to be used to indicate that there is no char index available.
......@@ -120,7 +114,8 @@ TtsController* TtsController::GetInstance() {
TtsController::TtsController()
: current_utterance_(NULL),
paused_(false),
platform_impl_(NULL) {
platform_impl_(NULL),
tts_engine_delegate_(NULL) {
}
TtsController::~TtsController() {
......@@ -177,6 +172,9 @@ void TtsController::SpeakNow(Utterance* utterance) {
if (native_voices.empty() && !voices.empty()) {
// TODO(dtseng): Notify extension caller of an error.
utterance->set_voice_name("");
// TODO(gaochun): Replace the global variable g_browser_process with
// GetContentClient()->browser() to eliminate the dependency of browser
// once TTS implementation was moved to content.
utterance->set_lang(g_browser_process->GetApplicationLocale());
index = GetMatchingVoice(utterance, voices);
......@@ -197,7 +195,8 @@ void TtsController::SpeakNow(Utterance* utterance) {
DCHECK(!voice.extension_id.empty());
current_utterance_ = utterance;
utterance->set_extension_id(voice.extension_id);
ExtensionTtsEngineSpeak(utterance, voice);
if (tts_engine_delegate_)
tts_engine_delegate_->Speak(utterance, voice);
bool sends_end_event =
voice.events.find(TTS_EVENT_END) != voice.events.end();
if (!sends_end_event) {
......@@ -241,7 +240,8 @@ void TtsController::Stop() {
paused_ = false;
if (current_utterance_ && !current_utterance_->extension_id().empty()) {
#if !defined(OS_ANDROID)
ExtensionTtsEngineStop(current_utterance_);
if (tts_engine_delegate_)
tts_engine_delegate_->Stop(current_utterance_);
#endif
} else {
GetPlatformImpl()->clear_error();
......@@ -259,7 +259,8 @@ void TtsController::Pause() {
paused_ = true;
if (current_utterance_ && !current_utterance_->extension_id().empty()) {
#if !defined(OS_ANDROID)
ExtensionTtsEnginePause(current_utterance_);
if (tts_engine_delegate_)
tts_engine_delegate_->Pause(current_utterance_);
#endif
} else if (current_utterance_) {
GetPlatformImpl()->clear_error();
......@@ -271,7 +272,8 @@ void TtsController::Resume() {
paused_ = false;
if (current_utterance_ && !current_utterance_->extension_id().empty()) {
#if !defined(OS_ANDROID)
ExtensionTtsEngineResume(current_utterance_);
if (tts_engine_delegate_)
tts_engine_delegate_->Resume(current_utterance_);
#endif
} else if (current_utterance_) {
GetPlatformImpl()->clear_error();
......@@ -302,8 +304,8 @@ void TtsController::OnTtsEvent(int utterance_id,
void TtsController::GetVoices(Profile* profile,
std::vector<VoiceData>* out_voices) {
#if !defined(OS_ANDROID)
if (profile)
GetExtensionVoices(profile, out_voices);
if (profile && tts_engine_delegate_)
tts_engine_delegate_->GetVoices(profile, out_voices);
#endif
TtsPlatformImpl* platform_impl = GetPlatformImpl();
......@@ -450,3 +452,8 @@ void TtsController::RemoveVoicesChangedDelegate(
VoicesChangedDelegate* delegate) {
voices_changed_delegates_.erase(delegate);
}
void TtsController::SetTtsEngineDelegate(
TtsEngineDelegate* delegate) {
tts_engine_delegate_ = delegate;
}
......@@ -77,6 +77,29 @@ struct VoiceData {
std::string native_voice_identifier;
};
// Interface that delegates TTS requests to user-installed extensions.
class TtsEngineDelegate {
public:
virtual ~TtsEngineDelegate() {}
// Return a list of all available voices registered.
virtual void GetVoices(Profile* profile,
std::vector<VoiceData>* out_voices) = 0;
// Speak the given utterance by sending an event to the given TTS engine.
virtual void Speak(Utterance* utterance, const VoiceData& voice) = 0;
// Stop speaking the given utterance by sending an event to the target
// associated with this utterance.
virtual void Stop(Utterance* utterance) = 0;
// Pause in the middle of speaking this utterance.
virtual void Pause(Utterance* utterance) = 0;
// Resume speaking this utterance.
virtual void Resume(Utterance* utterance) = 0;
};
// Class that wants to receive events on utterances.
class UtteranceEventDelegate {
public:
......@@ -297,6 +320,10 @@ class TtsController {
// Remove delegate that wants to be notified when the set of voices changes.
void RemoveVoicesChangedDelegate(VoicesChangedDelegate* delegate);
// Set the delegate that processes TTS requests with user-installed
// extensions.
void SetTtsEngineDelegate(TtsEngineDelegate* delegate);
// For unit testing.
void SetPlatformImpl(TtsPlatformImpl* platform_impl);
int QueueSize();
......@@ -346,6 +373,9 @@ class TtsController {
// dependency injection.
TtsPlatformImpl* platform_impl_;
// The delegate that processes TTS requests with user-installed extensions.
TtsEngineDelegate* tts_engine_delegate_;
DISALLOW_COPY_AND_ASSIGN(TtsController);
};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment