Commit cce93193 authored by Ryan Daum's avatar Ryan Daum Committed by Commit Bot

[chromecast] Begin unforking cast TTS controller

  * Change the TTS extension API to use the upstream TTS controller now
    that it's been moved out of chrome/ and into content/.
  * Requires downstream changes in internal/ to rework the platform,
    until those changes land, TTS will become a no-op.
  * Using upstream TtsController instead of our fork automagically
    makes it possible to enable and use the Speech Synthesis API

Bug: internal b/162974460
Merge-With: eureka-internal/434822
Test: manual, on device
Change-Id: I3acde313d177b74408394046a283b2da02dbff41
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2340703Reviewed-by: default avatarLuke Halliwell (slow) <halliwell@chromium.org>
Reviewed-by: default avatarSean Topping <seantopping@chromium.org>
Reviewed-by: default avatarDaniel Nicoara <dnicoara@chromium.org>
Reviewed-by: default avatarDominic Mazzoni <dmazzoni@chromium.org>
Reviewed-by: default avatarRandy Rossi <rmrossi@chromium.org>
Commit-Queue: Ryan Daum <rdaum@chromium.org>
Cr-Commit-Position: refs/heads/master@{#796433}
parent af87171f
...@@ -127,13 +127,6 @@ cast_source_set("browser") { ...@@ -127,13 +127,6 @@ cast_source_set("browser") {
"service/cast_service_simple.h", "service/cast_service_simple.h",
"service_connector.cc", "service_connector.cc",
"service_connector.h", "service_connector.h",
"tts/tts_controller.h",
"tts/tts_controller_impl.cc",
"tts/tts_controller_impl.h",
"tts/tts_platform.cc",
"tts/tts_platform.h",
"tts/tts_platform_stub.cc",
"tts/tts_platform_stub.h",
"webui/cast_resource_data_source.cc", "webui/cast_resource_data_source.cc",
"webui/cast_resource_data_source.h", "webui/cast_resource_data_source.h",
"webui/cast_webui.cc", "webui/cast_webui.cc",
......
...@@ -65,7 +65,7 @@ include_rules = [ ...@@ -65,7 +65,7 @@ include_rules = [
"+third_party/blink/public/mojom/loader/resource_load_info.mojom.h", "+third_party/blink/public/mojom/loader/resource_load_info.mojom.h",
"+third_party/blink/public/mojom/mediastream/media_stream.mojom-shared.h", "+third_party/blink/public/mojom/mediastream/media_stream.mojom-shared.h",
"+third_party/blink/public/mojom/messaging", "+third_party/blink/public/mojom/messaging",
"+third_party/blink/public/mojom/speech/speech_synthesis.mojom-forward.h", "+third_party/blink/public/mojom/speech/speech_synthesis.mojom.h",
"+third_party/skia/include/core/SkColor.h", "+third_party/skia/include/core/SkColor.h",
"+ui/accessibility", "+ui/accessibility",
"+ui/aura", "+ui/aura",
......
...@@ -44,8 +44,6 @@ ...@@ -44,8 +44,6 @@
#include "chromecast/browser/media/media_caps_impl.h" #include "chromecast/browser/media/media_caps_impl.h"
#include "chromecast/browser/metrics/cast_browser_metrics.h" #include "chromecast/browser/metrics/cast_browser_metrics.h"
#include "chromecast/browser/service_connector.h" #include "chromecast/browser/service_connector.h"
#include "chromecast/browser/tts/tts_controller_impl.h"
#include "chromecast/browser/tts/tts_platform_stub.h"
#include "chromecast/chromecast_buildflags.h" #include "chromecast/chromecast_buildflags.h"
#include "chromecast/graphics/cast_window_manager.h" #include "chromecast/graphics/cast_window_manager.h"
#include "chromecast/media/base/key_systems_common.h" #include "chromecast/media/base/key_systems_common.h"
...@@ -626,9 +624,6 @@ void CastBrowserMainParts::PreMainMessageLoopRun() { ...@@ -626,9 +624,6 @@ void CastBrowserMainParts::PreMainMessageLoopRun() {
::media::InitializeMediaLibrary(); ::media::InitializeMediaLibrary();
media_caps_->Initialize(); media_caps_->Initialize();
cast_browser_process_->SetTtsController(std::make_unique<TtsControllerImpl>(
std::make_unique<TtsPlatformImplStub>()));
#if BUILDFLAG(ENABLE_CHROMECAST_EXTENSIONS) #if BUILDFLAG(ENABLE_CHROMECAST_EXTENSIONS)
user_pref_service_ = extensions::cast_prefs::CreateUserPrefService( user_pref_service_ = extensions::cast_prefs::CreateUserPrefService(
cast_browser_process_->browser_context()); cast_browser_process_->browser_context());
......
...@@ -13,7 +13,6 @@ ...@@ -13,7 +13,6 @@
#include "chromecast/browser/cast_network_contexts.h" #include "chromecast/browser/cast_network_contexts.h"
#include "chromecast/browser/devtools/remote_debugging_server.h" #include "chromecast/browser/devtools/remote_debugging_server.h"
#include "chromecast/browser/metrics/cast_browser_metrics.h" #include "chromecast/browser/metrics/cast_browser_metrics.h"
#include "chromecast/browser/tts/tts_controller.h"
#include "chromecast/metrics/cast_metrics_service_client.h" #include "chromecast/metrics/cast_metrics_service_client.h"
#include "chromecast/net/connectivity_checker.h" #include "chromecast/net/connectivity_checker.h"
#include "chromecast/service/cast_service.h" #include "chromecast/service/cast_service.h"
...@@ -145,12 +144,6 @@ void CastBrowserProcess::SetNetLog(net::NetLog* net_log) { ...@@ -145,12 +144,6 @@ void CastBrowserProcess::SetNetLog(net::NetLog* net_log) {
net_log_ = net_log; net_log_ = net_log;
} }
void CastBrowserProcess::SetTtsController(
std::unique_ptr<TtsController> tts_controller) {
DCHECK(!tts_controller_);
tts_controller_ = std::move(tts_controller);
}
void CastBrowserProcess::SetWebViewFactory( void CastBrowserProcess::SetWebViewFactory(
CastWebViewFactory* web_view_factory) { CastWebViewFactory* web_view_factory) {
DCHECK(!web_view_factory_); DCHECK(!web_view_factory_);
......
...@@ -12,7 +12,6 @@ ...@@ -12,7 +12,6 @@
#include "build/build_config.h" #include "build/build_config.h"
#include "chromecast/chromecast_buildflags.h" #include "chromecast/chromecast_buildflags.h"
class TtsController;
class PrefService; class PrefService;
namespace net { namespace net {
...@@ -76,7 +75,6 @@ class CastBrowserProcess { ...@@ -76,7 +75,6 @@ class CastBrowserProcess {
void SetConnectivityChecker( void SetConnectivityChecker(
scoped_refptr<ConnectivityChecker> connectivity_checker); scoped_refptr<ConnectivityChecker> connectivity_checker);
void SetNetLog(net::NetLog* net_log); void SetNetLog(net::NetLog* net_log);
void SetTtsController(std::unique_ptr<TtsController> tts_controller);
void SetWebViewFactory(CastWebViewFactory* web_view_factory); void SetWebViewFactory(CastWebViewFactory* web_view_factory);
CastContentBrowserClient* browser_client() const { CastContentBrowserClient* browser_client() const {
...@@ -108,7 +106,6 @@ class CastBrowserProcess { ...@@ -108,7 +106,6 @@ class CastBrowserProcess {
return remote_debugging_server_.get(); return remote_debugging_server_.get();
} }
net::NetLog* net_log() const { return net_log_; } net::NetLog* net_log() const { return net_log_; }
TtsController* tts_controller() const { return tts_controller_.get(); }
CastWebViewFactory* web_view_factory() const { return web_view_factory_; } CastWebViewFactory* web_view_factory() const { return web_view_factory_; }
private: private:
...@@ -132,7 +129,6 @@ class CastBrowserProcess { ...@@ -132,7 +129,6 @@ class CastBrowserProcess {
CastWebViewFactory* web_view_factory_; CastWebViewFactory* web_view_factory_;
CastContentBrowserClient* cast_content_browser_client_; CastContentBrowserClient* cast_content_browser_client_;
net::NetLog* net_log_; net::NetLog* net_log_;
std::unique_ptr<TtsController> tts_controller_;
// Note: CastService must be destroyed before others. // Note: CastService must be destroyed before others.
std::unique_ptr<CastService> cast_service_; std::unique_ptr<CastService> cast_service_;
......
...@@ -49,7 +49,6 @@ ...@@ -49,7 +49,6 @@
#include "chromecast/browser/media/media_caps_impl.h" #include "chromecast/browser/media/media_caps_impl.h"
#include "chromecast/browser/service/cast_service_simple.h" #include "chromecast/browser/service/cast_service_simple.h"
#include "chromecast/browser/service_connector.h" #include "chromecast/browser/service_connector.h"
#include "chromecast/browser/tts/tts_controller.h"
#include "chromecast/common/cast_content_client.h" #include "chromecast/common/cast_content_client.h"
#include "chromecast/common/global_descriptors.h" #include "chromecast/common/global_descriptors.h"
#include "chromecast/media/audio/cast_audio_manager.h" #include "chromecast/media/audio/cast_audio_manager.h"
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
#include <string> #include <string>
#include "chromecast/browser/tts/tts_controller.h" #include "content/public/browser/tts_controller.h"
#include "extensions/browser/browser_context_keyed_api_factory.h" #include "extensions/browser/browser_context_keyed_api_factory.h"
#include "extensions/browser/extension_function.h" #include "extensions/browser/extension_function.h"
...@@ -20,8 +20,8 @@ namespace content { ...@@ -20,8 +20,8 @@ namespace content {
class BrowserContext; class BrowserContext;
} }
const char* TtsEventTypeToString(TtsEventType event_type); const char* TtsEventTypeToString(content::TtsEventType event_type);
TtsEventType TtsEventTypeFromString(const std::string& str); content::TtsEventType TtsEventTypeFromString(const std::string& str);
namespace extensions { namespace extensions {
......
...@@ -2,16 +2,12 @@ ...@@ -2,16 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// PLEASE NOTE: this is a copy with modifications from
// /chrome/browser/speech/extension_api
// It is temporary until a refactoring to move the chrome TTS implementation up
// into components and extensions/components can be completed.
#include "chromecast/browser/extensions/api/tts/tts_extension_api_constants.h" #include "chromecast/browser/extensions/api/tts/tts_extension_api_constants.h"
namespace tts_extension_api_constants { namespace tts_extension_api_constants {
const char kCharIndexKey[] = "charIndex"; const char kCharIndexKey[] = "charIndex";
const char kLengthKey[] = "length";
const char kDesiredEventTypesKey[] = "desiredEventTypes"; const char kDesiredEventTypesKey[] = "desiredEventTypes";
const char kEnqueueKey[] = "enqueue"; const char kEnqueueKey[] = "enqueue";
const char kErrorMessageKey[] = "errorMessage"; const char kErrorMessageKey[] = "errorMessage";
...@@ -30,9 +26,6 @@ const char kSrcIdKey[] = "srcId"; ...@@ -30,9 +26,6 @@ const char kSrcIdKey[] = "srcId";
const char kVoiceNameKey[] = "voiceName"; const char kVoiceNameKey[] = "voiceName";
const char kVolumeKey[] = "volume"; const char kVolumeKey[] = "volume";
const char kGenderFemale[] = "female";
const char kGenderMale[] = "male";
const char kEventTypeCancelled[] = "cancelled"; const char kEventTypeCancelled[] = "cancelled";
const char kEventTypeEnd[] = "end"; const char kEventTypeEnd[] = "end";
const char kEventTypeError[] = "error"; const char kEventTypeError[] = "error";
...@@ -45,7 +38,6 @@ const char kEventTypeStart[] = "start"; ...@@ -45,7 +38,6 @@ const char kEventTypeStart[] = "start";
const char kEventTypeWord[] = "word"; const char kEventTypeWord[] = "word";
const char kErrorExtensionIdMismatch[] = "Extension id mismatch."; const char kErrorExtensionIdMismatch[] = "Extension id mismatch.";
const char kErrorInvalidGender[] = "Invalid gender.";
const char kErrorInvalidLang[] = "Invalid lang."; const char kErrorInvalidLang[] = "Invalid lang.";
const char kErrorInvalidPitch[] = "Invalid pitch."; const char kErrorInvalidPitch[] = "Invalid pitch.";
const char kErrorInvalidRate[] = "Invalid rate."; const char kErrorInvalidRate[] = "Invalid rate.";
......
...@@ -2,11 +2,6 @@ ...@@ -2,11 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// PLEASE NOTE: this is a copy with modifications from
// /chrome/browser/speech/extension_api
// It is temporary until a refactoring to move the chrome TTS implementation up
// into components and extensions/components can be completed.
#ifndef CHROMECAST_BROWSER_EXTENSIONS_API_TTS_TTS_EXTENSION_API_CONSTANTS_H_ #ifndef CHROMECAST_BROWSER_EXTENSIONS_API_TTS_TTS_EXTENSION_API_CONSTANTS_H_
#define CHROMECAST_BROWSER_EXTENSIONS_API_TTS_TTS_EXTENSION_API_CONSTANTS_H_ #define CHROMECAST_BROWSER_EXTENSIONS_API_TTS_TTS_EXTENSION_API_CONSTANTS_H_
...@@ -17,6 +12,7 @@ ...@@ -17,6 +12,7 @@
namespace tts_extension_api_constants { namespace tts_extension_api_constants {
extern const char kCharIndexKey[]; extern const char kCharIndexKey[];
extern const char kLengthKey[];
extern const char kDesiredEventTypesKey[]; extern const char kDesiredEventTypesKey[];
extern const char kEnqueueKey[]; extern const char kEnqueueKey[];
extern const char kErrorMessageKey[]; extern const char kErrorMessageKey[];
...@@ -35,9 +31,6 @@ extern const char kSrcIdKey[]; ...@@ -35,9 +31,6 @@ extern const char kSrcIdKey[];
extern const char kVoiceNameKey[]; extern const char kVoiceNameKey[];
extern const char kVolumeKey[]; extern const char kVolumeKey[];
extern const char kGenderFemale[];
extern const char kGenderMale[];
extern const char kEventTypeCancelled[]; extern const char kEventTypeCancelled[];
extern const char kEventTypeEnd[]; extern const char kEventTypeEnd[];
extern const char kEventTypeError[]; extern const char kEventTypeError[];
...@@ -50,7 +43,6 @@ extern const char kEventTypeStart[]; ...@@ -50,7 +43,6 @@ extern const char kEventTypeStart[];
extern const char kEventTypeWord[]; extern const char kEventTypeWord[];
extern const char kErrorExtensionIdMismatch[]; extern const char kErrorExtensionIdMismatch[];
extern const char kErrorInvalidGender[];
extern const char kErrorInvalidLang[]; extern const char kErrorInvalidLang[];
extern const char kErrorInvalidPitch[]; extern const char kErrorInvalidPitch[];
extern const char kErrorInvalidRate[]; extern const char kErrorInvalidRate[];
......
// Copyright (c) 2018 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.
#ifndef CHROMECAST_BROWSER_TTS_TTS_CONTROLLER_H_
#define CHROMECAST_BROWSER_TTS_TTS_CONTROLLER_H_
#include <memory>
#include <queue>
#include <set>
#include <string>
#include <vector>
#include "base/memory/singleton.h"
#include "base/memory/weak_ptr.h"
#include "url/gurl.h"
class Utterance;
class TtsPlatformImpl;
namespace base {
class Value;
} // namespace base
namespace content {
class BrowserContext;
} // namespace content
// Events sent back from the TTS engine indicating the progress.
enum TtsEventType {
TTS_EVENT_START,
TTS_EVENT_END,
TTS_EVENT_WORD,
TTS_EVENT_SENTENCE,
TTS_EVENT_MARKER,
TTS_EVENT_INTERRUPTED,
TTS_EVENT_CANCELLED,
TTS_EVENT_ERROR,
TTS_EVENT_PAUSE,
TTS_EVENT_RESUME
};
enum TtsGenderType { TTS_GENDER_NONE, TTS_GENDER_MALE, TTS_GENDER_FEMALE };
// Returns true if this event type is one that indicates an utterance
// is finished and can be destroyed.
bool IsFinalTtsEventType(TtsEventType event_type);
// The continuous parameters that apply to a given utterance.
struct UtteranceContinuousParameters {
UtteranceContinuousParameters();
double rate;
double pitch;
double volume;
};
// Information about one voice.
struct VoiceData {
VoiceData();
VoiceData(const VoiceData& other);
~VoiceData();
std::string name;
std::string lang;
TtsGenderType gender;
std::string extension_id; // Not used in cast.
std::set<TtsEventType> events;
// If true, the synthesis engine is a remote network resource.
// It may be higher latency and may incur bandwidth costs.
bool remote;
// If true, this is implemented by this platform's subclass of
// TtsPlatformImpl. If false, this is implemented by an extension.
bool native;
std::string native_voice_identifier;
};
// Class that wants to receive events on utterances.
class UtteranceEventDelegate {
public:
virtual ~UtteranceEventDelegate() {}
virtual void OnTtsEvent(Utterance* utterance,
TtsEventType event_type,
int char_index,
const std::string& error_message) = 0;
};
// One speech utterance.
class Utterance {
public:
// Construct an utterance given a profile and a completion task to call
// when the utterance is done speaking. Before speaking this utterance,
// its other parameters like text, rate, pitch, etc. should all be set.
explicit Utterance(content::BrowserContext* browser_context);
~Utterance();
// Sends an event to the delegate. If the event type is TTS_EVENT_END
// or TTS_EVENT_ERROR, deletes the utterance. If |char_index| is -1,
// uses the last good value.
void OnTtsEvent(TtsEventType event_type,
int char_index,
const std::string& error_message);
// Finish an utterance without sending an event to the delegate.
void Finish();
// Getters and setters for the text to speak and other speech options.
void set_text(const std::string& text) { text_ = text; }
const std::string& text() const { return text_; }
void set_options(const base::Value* options);
const base::Value* options() const { return options_.get(); }
void set_src_id(int src_id) { src_id_ = src_id; }
int src_id() { return src_id_; }
void set_src_url(const GURL& src_url) { src_url_ = src_url; }
const GURL& src_url() { return src_url_; }
void set_voice_name(const std::string& voice_name) {
voice_name_ = voice_name;
}
const std::string& voice_name() const { return voice_name_; }
void set_lang(const std::string& lang) { lang_ = lang; }
const std::string& lang() const { return lang_; }
void set_gender(TtsGenderType gender) { gender_ = gender; }
TtsGenderType gender() const { return gender_; }
void set_continuous_parameters(const double rate,
const double pitch,
const double volume) {
continuous_parameters_.rate = rate;
continuous_parameters_.pitch = pitch;
continuous_parameters_.volume = volume;
}
const UtteranceContinuousParameters& continuous_parameters() {
return continuous_parameters_;
}
void set_can_enqueue(bool can_enqueue) { can_enqueue_ = can_enqueue; }
bool can_enqueue() const { return can_enqueue_; }
void set_required_event_types(const std::set<TtsEventType>& types) {
required_event_types_ = types;
}
const std::set<TtsEventType>& required_event_types() const {
return required_event_types_;
}
void set_desired_event_types(const std::set<TtsEventType>& types) {
desired_event_types_ = types;
}
const std::set<TtsEventType>& desired_event_types() const {
return desired_event_types_;
}
const std::string& extension_id() const { return extension_id_; }
void set_extension_id(const std::string& extension_id) {
extension_id_ = extension_id;
}
UtteranceEventDelegate* event_delegate() const { return event_delegate_; }
void set_event_delegate(UtteranceEventDelegate* event_delegate) {
event_delegate_ = event_delegate;
}
// Getters and setters for internal state.
content::BrowserContext* browser_context() const { return browser_context_; }
int id() const { return id_; }
bool finished() const { return finished_; }
private:
// The BrowserContext that initiated this utterance.
content::BrowserContext* browser_context_;
// The extension ID of the extension providing TTS for this utterance, or
// empty if native TTS is being used.
std::string extension_id_;
// The unique ID of this utterance, used to associate callback functions
// with utterances.
int id_;
// The id of the next utterance, so we can associate requests with
// responses.
static int next_utterance_id_;
// The text to speak.
std::string text_;
// The full options arg passed to tts.speak, which may include fields
// other than the ones we explicitly parse, below.
std::unique_ptr<base::Value> options_;
// The source extension's ID of this utterance, so that it can associate
// events with the appropriate callback.
int src_id_;
// The URL of the page where the source extension called speak.
GURL src_url_;
// The delegate to be called when an utterance event is fired.
UtteranceEventDelegate* event_delegate_;
// The parsed options.
std::string voice_name_;
std::string lang_;
TtsGenderType gender_;
UtteranceContinuousParameters continuous_parameters_;
bool can_enqueue_;
std::set<TtsEventType> required_event_types_;
std::set<TtsEventType> desired_event_types_;
// The index of the current char being spoken.
int char_index_;
// True if this utterance received an event indicating it's done.
bool finished_;
};
// Singleton class that manages text-to-speech for the TTS extension APIs,
// potentially maintaining a queue of pending utterances and keeping track of
// all state.
class TtsController {
public:
virtual ~TtsController() = default;
// Set the TTS platform implementation to use.
virtual void SetPlatformImpl(
std::unique_ptr<TtsPlatformImpl> platform_impl) = 0;
// Returns true if we're currently speaking an utterance.
virtual bool IsSpeaking() = 0;
// Speak the given utterance. If the utterance's can_enqueue flag is true
// and another utterance is in progress, adds it to the end of the queue.
// Otherwise, interrupts any current utterance and speaks this one
// immediately.
virtual void SpeakOrEnqueue(Utterance* utterance) = 0;
// Stop all utterances and flush the queue. Implies leaving pause mode
// as well.
virtual void Stop() = 0;
// Pause the speech queue. Some engines may support pausing in the middle
// of an utterance.
virtual void Pause() = 0;
// Resume speaking.
virtual void Resume() = 0;
// Handle events received from the speech engine. Events are forwarded to
// the callback function, and in addition, completion and error events
// trigger finishing the current utterance and starting the next one, if
// any.
virtual void OnTtsEvent(int utterance_id,
TtsEventType event_type,
int char_index,
const std::string& error_message) = 0;
// Return a list of all available voices, including the native voice,
// if supported, and all voices registered by extensions.
virtual void GetVoices(content::BrowserContext* browser_context,
std::vector<VoiceData>* out_voices) = 0;
// For unit testing.
virtual int QueueSize() = 0;
};
#endif // CHROMECAST_BROWSER_TTS_TTS_CONTROLLER_H_
This diff is collapsed.
// Copyright 2018 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.
#ifndef CHROMECAST_BROWSER_TTS_TTS_CONTROLLER_IMPL_H_
#define CHROMECAST_BROWSER_TTS_TTS_CONTROLLER_IMPL_H_
#include <memory>
#include <set>
#include <string>
#include <vector>
#include "base/containers/queue.h"
#include "base/gtest_prod_util.h"
#include "base/macros.h"
#include "base/memory/singleton.h"
#include "chromecast/browser/tts/tts_controller.h"
#include "url/gurl.h"
namespace content {
class BrowserContext;
} // namespace content
// Singleton class that manages text-to-speech for the TTS and TTS engine
// extension APIs, maintaining a queue of pending utterances and keeping
// track of all state.
class TtsControllerImpl : public TtsController {
public:
explicit TtsControllerImpl(std::unique_ptr<TtsPlatformImpl> platform_impl);
~TtsControllerImpl() override;
// TtsController methods
bool IsSpeaking() override;
void SpeakOrEnqueue(Utterance* utterance) override;
void Stop() override;
void Pause() override;
void Resume() override;
void OnTtsEvent(int utterance_id,
TtsEventType event_type,
int char_index,
const std::string& error_message) override;
void GetVoices(content::BrowserContext* browser_context,
std::vector<VoiceData>* out_voices) override;
void SetPlatformImpl(std::unique_ptr<TtsPlatformImpl> platform_impl) override;
int QueueSize() override;
std::string GetApplicationLocale() const;
private:
FRIEND_TEST_ALL_PREFIXES(TtsControllerTest, TestGetMatchingVoice);
FRIEND_TEST_ALL_PREFIXES(TtsControllerTest,
TestTtsControllerUtteranceDefaults);
// Get the platform TTS implementation (or injected mock).
TtsPlatformImpl* GetPlatformImpl();
// Start speaking the given utterance. Will either take ownership of
// |utterance| or delete it if there's an error. Returns true on success.
void SpeakNow(Utterance* utterance);
// Clear the utterance queue. If send_events is true, will send
// TTS_EVENT_CANCELLED events on each one.
void ClearUtteranceQueue(bool send_events);
// Finalize and delete the current utterance.
void FinishCurrentUtterance();
// Start speaking the next utterance in the queue.
void SpeakNextUtterance();
// Given an utterance and a vector of voices, return the
// index of the voice that best matches the utterance.
int GetMatchingVoice(const Utterance* utterance,
std::vector<VoiceData>& voices);
// Updates the utterance to have default values for rate, pitch, and
// volume if they have not yet been set. On Chrome OS, defaults are
// pulled from user prefs, and may not be the same as other platforms.
void UpdateUtteranceDefaults(Utterance* utterance);
// The current utterance being spoken.
Utterance* current_utterance_;
// Whether the queue is paused or not.
bool paused_;
// A queue of utterances to speak after the current one finishes.
base::queue<Utterance*> utterance_queue_;
// A pointer to the platform implementation of text-to-speech.
std::unique_ptr<TtsPlatformImpl> platform_impl_;
DISALLOW_COPY_AND_ASSIGN(TtsControllerImpl);
};
#endif // CHROMECAST_BROWSER_TTS_TTS_CONTROLLER_IMPL_H_
// Copyright (c) 2018 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.
// Unit tests for the TTS Controller.
#include "base/values.h"
#include "chromecast/browser/tts/tts_controller_impl.h"
#include "chromecast/browser/tts/tts_platform.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/testing_pref_service.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/platform/web_speech_synthesis_constants.h"
namespace chromecast {
class TtsControllerTest : public testing::Test {};
// Platform Tts implementation that does nothing.
class DummyTtsPlatformImpl : public TtsPlatformImpl {
public:
DummyTtsPlatformImpl() {}
~DummyTtsPlatformImpl() override {}
bool PlatformImplAvailable() override { return true; }
bool Speak(int utterance_id,
const std::string& utterance,
const std::string& lang,
const VoiceData& voice,
const UtteranceContinuousParameters& params) override {
return true;
}
bool IsSpeaking() override { return false; }
bool StopSpeaking() override { return true; }
void Pause() override {}
void Resume() override {}
void GetVoices(std::vector<VoiceData>* out_voices) override {}
std::string error() override { return std::string(); }
void clear_error() override {}
void set_error(const std::string& error) override {}
};
// Subclass of TtsController with a public ctor and dtor.
class TestableTtsController : public TtsControllerImpl {
public:
TestableTtsController() {}
~TestableTtsController() override {}
};
TEST_F(TtsControllerTest, TestTtsControllerShutdown) {
DummyTtsPlatformImpl platform_impl;
TestableTtsController* controller = new TestableTtsController();
controller->SetPlatformImpl(&platform_impl);
Utterance* utterance1 = new Utterance(nullptr);
utterance1->set_can_enqueue(true);
utterance1->set_src_id(1);
controller->SpeakOrEnqueue(utterance1);
Utterance* utterance2 = new Utterance(nullptr);
utterance2->set_can_enqueue(true);
utterance2->set_src_id(2);
controller->SpeakOrEnqueue(utterance2);
// Make sure that deleting the controller when there are pending
// utterances doesn't cause a crash.
delete controller;
}
TEST_F(TtsControllerTest, TestGetMatchingVoice) {
TtsControllerImpl* tts_controller = TtsControllerImpl::GetInstance();
{
// Calling GetMatchingVoice with no voices returns -1.
Utterance utterance(nullptr);
std::vector<VoiceData> voices;
EXPECT_EQ(-1, tts_controller->GetMatchingVoice(&utterance, voices));
}
{
// Calling GetMatchingVoice with any voices returns the first one
// even if there are no criteria that match.
Utterance utterance(nullptr);
std::vector<VoiceData> voices;
voices.push_back(VoiceData());
voices.push_back(VoiceData());
EXPECT_EQ(0, tts_controller->GetMatchingVoice(&utterance, voices));
}
{
// If nothing else matches, the English voice is returned.
// (In tests the language will always be English.)
Utterance utterance(nullptr);
std::vector<VoiceData> voices;
VoiceData fr_voice;
fr_voice.lang = "fr";
voices.push_back(fr_voice);
VoiceData en_voice;
en_voice.lang = "en";
voices.push_back(en_voice);
VoiceData de_voice;
de_voice.lang = "de";
voices.push_back(de_voice);
EXPECT_EQ(1, tts_controller->GetMatchingVoice(&utterance, voices));
}
{
// Check precedence of various matching criteria.
std::vector<VoiceData> voices;
VoiceData voice0;
voices.push_back(voice0);
VoiceData voice1;
voice1.gender = TTS_GENDER_FEMALE;
voices.push_back(voice1);
VoiceData voice2;
voice2.events.insert(TTS_EVENT_WORD);
voices.push_back(voice2);
VoiceData voice3;
voice3.lang = "de-DE";
voices.push_back(voice3);
VoiceData voice4;
voice4.lang = "fr-CA";
voices.push_back(voice4);
VoiceData voice5;
voice5.name = "Voice5";
voices.push_back(voice5);
VoiceData voice6;
voice6.extension_id = "id6";
voices.push_back(voice6);
Utterance utterance(nullptr);
EXPECT_EQ(0, tts_controller->GetMatchingVoice(&utterance, voices));
utterance.set_gender(TTS_GENDER_FEMALE);
EXPECT_EQ(1, tts_controller->GetMatchingVoice(&utterance, voices));
std::set<TtsEventType> types;
types.insert(TTS_EVENT_WORD);
utterance.set_required_event_types(types);
EXPECT_EQ(2, tts_controller->GetMatchingVoice(&utterance, voices));
utterance.set_lang("de-DE");
EXPECT_EQ(3, tts_controller->GetMatchingVoice(&utterance, voices));
utterance.set_lang("fr-FR");
EXPECT_EQ(4, tts_controller->GetMatchingVoice(&utterance, voices));
utterance.set_voice_name("Voice5");
EXPECT_EQ(5, tts_controller->GetMatchingVoice(&utterance, voices));
utterance.set_voice_name("");
utterance.set_extension_id("id6");
EXPECT_EQ(6, tts_controller->GetMatchingVoice(&utterance, voices));
}
}
} // namespace chromecast
// Copyright (c) 2018 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 "chromecast/browser/tts/tts_platform.h"
#include <string>
std::string TtsPlatformImpl::error() {
return error_;
}
void TtsPlatformImpl::clear_error() {
error_ = std::string();
}
void TtsPlatformImpl::set_error(const std::string& error) {
error_ = error;
}
void TtsPlatformImpl::WillSpeakUtteranceWithVoice(const Utterance* utterance,
const VoiceData& voice_data) {
}
// Copyright (c) 2018 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.
#ifndef CHROMECAST_BROWSER_TTS_TTS_PLATFORM_H_
#define CHROMECAST_BROWSER_TTS_TTS_PLATFORM_H_
#include <string>
#include "base/macros.h"
#include "chromecast/browser/tts/tts_controller.h"
// Abstract class that defines the native platform TTS interface,
// subclassed by specific implementations on Win, Mac, etc.
class TtsPlatformImpl {
public:
TtsPlatformImpl() {}
virtual ~TtsPlatformImpl() {}
// Returns true if this platform implementation is supported and available.
virtual bool PlatformImplAvailable() = 0;
// Speak the given utterance with the given parameters if possible,
// and return true on success. Utterance will always be nonempty.
// If rate, pitch, or volume are -1.0, they will be ignored.
//
// The TtsController will only try to speak one utterance at
// a time. If it wants to interrupt speech, it will always call Stop
// before speaking again.
virtual bool Speak(int utterance_id,
const std::string& utterance,
const std::string& lang,
const VoiceData& voice,
const UtteranceContinuousParameters& params) = 0;
// Stop speaking immediately and return true on success.
virtual bool StopSpeaking() = 0;
// Returns whether any speech is on going.
virtual bool IsSpeaking() = 0;
// Append information about voices provided by this platform implementation
// to |out_voices|.
virtual void GetVoices(std::vector<VoiceData>* out_voices) = 0;
// Pause the current utterance, if any, until a call to Resume,
// Speak, or StopSpeaking.
virtual void Pause() = 0;
// Resume speaking the current utterance, if it was paused.
virtual void Resume() = 0;
// Allows the platform to monitor speech commands and the voices used
// for each one.
virtual void WillSpeakUtteranceWithVoice(const Utterance* utterance,
const VoiceData& voice_data);
virtual std::string error();
virtual void clear_error();
virtual void set_error(const std::string& error);
protected:
std::string error_;
DISALLOW_COPY_AND_ASSIGN(TtsPlatformImpl);
};
#endif // CHROMECAST_BROWSER_TTS_TTS_PLATFORM_H_
// Copyright (c) 2018 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 "chromecast/browser/tts/tts_platform_stub.h"
#include "base/logging.h"
namespace chromecast {
bool TtsPlatformImplStub::PlatformImplAvailable() {
return true;
}
bool TtsPlatformImplStub::Speak(int utterance_id,
const std::string& utterance,
const std::string& lang,
const VoiceData& voice,
const UtteranceContinuousParameters& params) {
LOG(INFO) << "Speak: " << utterance;
return true;
}
bool TtsPlatformImplStub::StopSpeaking() {
LOG(INFO) << "StopSpeaking";
return true;
}
void TtsPlatformImplStub::Pause() {
LOG(INFO) << "Pause";
}
void TtsPlatformImplStub::Resume() {
LOG(INFO) << "Resume";
}
bool TtsPlatformImplStub::IsSpeaking() {
LOG(INFO) << "IsSpeaking";
return false;
}
void TtsPlatformImplStub::GetVoices(std::vector<VoiceData>* out_voices) {
LOG(INFO) << "GetVoices";
}
} // namespace chromecast
// Copyright (c) 2018 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 "chromecast/browser/tts/tts_controller.h"
#include "chromecast/browser/tts/tts_platform.h"
#ifndef CHROMECAST_BROWSER_TTS_TTS_PLATFORM_STUB_H_
#define CHROMECAST_BROWSER_TTS_TTS_PLATFORM_STUB_H_
namespace chromecast {
// The default stub implementation of TtsPlaform for Cast that merely logs TTS
// events.
class TtsPlatformImplStub : public TtsPlatformImpl {
public:
TtsPlatformImplStub() = default;
~TtsPlatformImplStub() override = default;
bool PlatformImplAvailable() override;
bool Speak(int utterance_id,
const std::string& utterance,
const std::string& lang,
const VoiceData& voice,
const UtteranceContinuousParameters& params) override;
bool StopSpeaking() override;
void Pause() override;
void Resume() override;
bool IsSpeaking() override;
void GetVoices(std::vector<VoiceData>* out_voices) override;
private:
DISALLOW_COPY_AND_ASSIGN(TtsPlatformImplStub);
};
} // namespace chromecast
#endif // CHROMECAST_BROWSER_TTS_TTS_PLATFORM_STUB_H_
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