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