Skip to content

Commit

Permalink
Rename TtsUtterance::*CanEnqueue to TtsUtterance::*ShouldClearQueue
Browse files Browse the repository at this point in the history
TtsController owns a queue of TtsUtterance objects. On each call to
SpeakOrEnqueue, the queue is processed in some way:
- if the utterance requests a clear, the queue is cleared, and the
utterance is enqueued (maybe implicitly via immediate processing)
- if the utterance doesn't request a clear, the utterance is simply
  enqueued

If the controller isn't ready (e.g. built in voices are loading,
platform is initializing), or if the controller is in a paused state,
processing ends.

Otherwise, in both of the above cases thereafter, the queue is
immediately processed (e.g. the controller begins dequeueing and
speaking utterances in fifo order).

Prior to this change, the "CanEnqueue" naming became somewhat misleading
when dealing with utterances especially in paused/not ready scenarios;
issue fixed here:
https://chromium-review.googlesource.com/c/chromium/src/+/2543374

This change follows up by adjusting naming accordingly.

R=avi@chromium.org, dmazzoni@chromium.org
TBR=seantopping@chromium.org

Change-Id: I30881e22b14b774220af1f7364ee1050bdd789d6
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2550430
Commit-Queue: David Tseng <dtseng@chromium.org>
Reviewed-by: Avi Drissman <avi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#829464}
  • Loading branch information
dtsengchromium authored and Commit Bot committed Nov 20, 2020
1 parent 116fc64 commit c06cdad
Show file tree
Hide file tree
Showing 11 changed files with 50 additions and 41 deletions.
2 changes: 1 addition & 1 deletion chrome/browser/chromeos/input_method/tts_handler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ void TtsHandler::Speak(const std::string& text) {
content::TtsUtterance::Create(profile_);
utterance->SetText(text);
utterance->SetEventDelegate(this);
utterance->SetCanEnqueue(true);
utterance->SetShouldClearQueue(false);

auto* tts_controller = content::TtsController::GetInstance();
tts_controller->SpeakOrEnqueue(std::move(utterance));
Expand Down
2 changes: 1 addition & 1 deletion chrome/browser/speech/extension_api/tts_extension_api.cc
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ ExtensionFunction::ResponseAction TtsSpeakFunction::Run() {
utterance->SetSrcUrl(source_url());
utterance->SetLang(lang);
utterance->SetContinuousParameters(rate, pitch, volume);
utterance->SetCanEnqueue(can_enqueue);
utterance->SetShouldClearQueue(!can_enqueue);
utterance->SetRequiredEventTypes(required_event_types);
utterance->SetDesiredEventTypes(desired_event_types);
utterance->SetEngineId(voice_extension_id);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,19 @@
// browser_tests.exe --gtest_filter="TtsApiTest.*"

chrome.test.runTests([function testPauseCancel() {
let gotSecondSpeak = false;
chrome.tts.pause();
chrome.tts.speak('text 1', {'enqueue': true});
chrome.tts.speak('text 1', {
'enqueue': true,
'onEvent': event => {
if (event.type == 'cancelled' && gotSecondSpeak) {
chrome.test.succeed();
}
}
});
chrome.tts.speak('text 2', {'enqueue': false}, function() {
chrome.test.assertNoLastError();
chrome.test.succeed();
gotSecondSpeak = true;
});
chrome.tts.resume();
}]);
2 changes: 1 addition & 1 deletion chromecast/browser/extensions/api/tts/tts_extension_api.cc
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ ExtensionFunction::ResponseAction TtsSpeakFunction::Run() {
utterance->SetSrcUrl(source_url());
utterance->SetLang(lang);
utterance->SetContinuousParameters(rate, pitch, volume);
utterance->SetCanEnqueue(can_enqueue);
utterance->SetShouldClearQueue(!can_enqueue);
utterance->SetRequiredEventTypes(required_event_types);
utterance->SetDesiredEventTypes(desired_event_types);
utterance->SetEngineId(voice_extension_id);
Expand Down
2 changes: 1 addition & 1 deletion content/browser/speech/speech_synthesis_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ void SpeechSynthesisImpl::Speak(
tts_utterance->SetText(utterance->text);
tts_utterance->SetLang(utterance->lang);
tts_utterance->SetVoiceName(utterance->voice);
tts_utterance->SetCanEnqueue(true);
tts_utterance->SetShouldClearQueue(false);
tts_utterance->SetContinuousParameters(utterance->rate, utterance->pitch,
utterance->volume);

Expand Down
8 changes: 3 additions & 5 deletions content/browser/speech/tts_controller_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -133,25 +133,23 @@ void TtsControllerImpl::SpeakOrEnqueue(
// engine implementation. Every utterances are postponed until the platform
// specific implementation is loaded to avoid racy behaviors.
if (TtsPlatformLoading()) {
bool can_enqueue = utterance->GetCanEnqueue();
if (!can_enqueue)
if (utterance->GetShouldClearQueue())
ClearUtteranceQueue(true);

utterance_list_.emplace_back(std::move(utterance));

return;
}

// If we're paused and we get an utterance that can't be queued,
// flush the queue but stay in the paused state.
if (paused_ && !utterance->GetCanEnqueue()) {
if (paused_ && utterance->GetShouldClearQueue()) {
Stop();
utterance_list_.emplace_back(std::move(utterance));
paused_ = true;
return;
}

if (paused_ || (IsSpeaking() && utterance->GetCanEnqueue())) {
if (paused_ || (IsSpeaking() && !utterance->GetShouldClearQueue())) {
utterance_list_.emplace_back(std::move(utterance));
} else {
Stop();
Expand Down
32 changes: 16 additions & 16 deletions content/browser/speech/tts_controller_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -232,12 +232,12 @@ class TtsControllerTest : public testing::Test {

TEST_F(TtsControllerTest, TestTtsControllerShutdown) {
std::unique_ptr<TtsUtterance> utterance1 = TtsUtterance::Create();
utterance1->SetCanEnqueue(true);
utterance1->SetShouldClearQueue(false);
utterance1->SetSrcId(1);
controller()->SpeakOrEnqueue(std::move(utterance1));

std::unique_ptr<TtsUtterance> utterance2 = TtsUtterance::Create();
utterance2->SetCanEnqueue(true);
utterance2->SetShouldClearQueue(false);
utterance2->SetSrcId(2);
controller()->SpeakOrEnqueue(std::move(utterance2));

Expand All @@ -259,7 +259,7 @@ TEST_F(TtsControllerTest, TestBrowserContextRemoved) {
std::unique_ptr<TtsUtterance> utterance1 =
TtsUtterance::Create(browser_context());
utterance1->SetEngineId("x");
utterance1->SetCanEnqueue(true);
utterance1->SetShouldClearQueue(false);
utterance1->SetSrcId(1);
controller()->SpeakOrEnqueue(std::move(utterance1));

Expand All @@ -271,7 +271,7 @@ TEST_F(TtsControllerTest, TestBrowserContextRemoved) {
std::unique_ptr<TtsUtterance> utterance2 =
TtsUtterance::Create(browser_context());
utterance2->SetEngineId("x");
utterance2->SetCanEnqueue(true);
utterance2->SetShouldClearQueue(false);
utterance2->SetSrcId(2);
controller()->SpeakOrEnqueue(std::move(utterance2));

Expand Down Expand Up @@ -487,7 +487,7 @@ TEST_F(TtsControllerTest, StartsQueuedUtteranceWhenWebContentsDestroyed) {
void* raw_utterance1 = utterance1.get();
std::unique_ptr<TtsUtteranceImpl> utterance2 =
CreateUtteranceImpl(web_contents2.get());
utterance2->SetCanEnqueue(true);
utterance2->SetShouldClearQueue(false);
void* raw_utterance2 = utterance2.get();

controller()->SpeakOrEnqueue(std::move(utterance1));
Expand All @@ -514,8 +514,8 @@ TEST_F(TtsControllerTest, StartsQueuedUtteranceWhenWebContentsDestroyed2) {
std::unique_ptr<TtsUtteranceImpl> utterance3 =
CreateUtteranceImpl(web_contents2.get());
void* raw_utterance3 = utterance3.get();
utterance2->SetCanEnqueue(true);
utterance3->SetCanEnqueue(true);
utterance2->SetShouldClearQueue(false);
utterance3->SetShouldClearQueue(false);

controller()->SpeakOrEnqueue(std::move(utterance1));
controller()->SpeakOrEnqueue(std::move(utterance2));
Expand Down Expand Up @@ -566,7 +566,7 @@ TEST_F(TtsControllerTest, SkipsQueuedUtteranceFromHiddenWebContents) {
const int utterance1_id = utterance1->GetId();
std::unique_ptr<TtsUtteranceImpl> utterance2 =
CreateUtteranceImpl(web_contents2.get());
utterance2->SetCanEnqueue(true);
utterance2->SetShouldClearQueue(false);

controller()->SpeakOrEnqueue(std::move(utterance1));
EXPECT_TRUE(TtsControllerCurrentUtterance());
Expand Down Expand Up @@ -600,7 +600,7 @@ TEST_F(TtsControllerTest, SpeakPauseResume) {
std::unique_ptr<WebContents> web_contents = CreateWebContents();
std::unique_ptr<TtsUtteranceImpl> utterance =
CreateUtteranceImpl(web_contents.get());
utterance->SetCanEnqueue(true);
utterance->SetShouldClearQueue(false);

// Start speaking an utterance.
controller()->SpeakOrEnqueue(std::move(utterance));
Expand Down Expand Up @@ -640,7 +640,7 @@ TEST_F(TtsControllerTest, SpeakWhenPaused) {
std::unique_ptr<WebContents> web_contents = CreateWebContents();
std::unique_ptr<TtsUtteranceImpl> utterance =
CreateUtteranceImpl(web_contents.get());
utterance->SetCanEnqueue(true);
utterance->SetShouldClearQueue(false);

// Pause the controller.
controller()->Pause();
Expand Down Expand Up @@ -676,7 +676,7 @@ TEST_F(TtsControllerTest, SpeakWhenPausedAndCannotEnqueueUtterance) {
std::unique_ptr<WebContents> web_contents = CreateWebContents();
std::unique_ptr<TtsUtteranceImpl> utterance1 =
CreateUtteranceImpl(web_contents.get());
utterance1->SetCanEnqueue(false);
utterance1->SetShouldClearQueue(true);

// Pause the controller.
controller()->Pause();
Expand All @@ -693,7 +693,7 @@ TEST_F(TtsControllerTest, SpeakWhenPausedAndCannotEnqueueUtterance) {
// and the second utterance must be queued with the first also queued.
std::unique_ptr<TtsUtteranceImpl> utterance2 =
CreateUtteranceImpl(web_contents.get());
utterance2->SetCanEnqueue(true);
utterance2->SetShouldClearQueue(false);

controller()->SpeakOrEnqueue(std::move(utterance2));
EXPECT_TRUE(controller()->IsPausedForTesting());
Expand All @@ -705,7 +705,7 @@ TEST_F(TtsControllerTest, SpeakWhenPausedAndCannotEnqueueUtterance) {
// enqueue the new utterance.
std::unique_ptr<TtsUtteranceImpl> utterance3 =
CreateUtteranceImpl(web_contents.get());
utterance3->SetCanEnqueue(false);
utterance3->SetShouldClearQueue(true);

controller()->SpeakOrEnqueue(std::move(utterance3));
EXPECT_TRUE(controller()->IsPausedForTesting());
Expand All @@ -722,7 +722,7 @@ TEST_F(TtsControllerTest, StopMustResumeController) {
std::unique_ptr<WebContents> web_contents = CreateWebContents();
std::unique_ptr<TtsUtteranceImpl> utterance =
CreateUtteranceImpl(web_contents.get());
utterance->SetCanEnqueue(true);
utterance->SetShouldClearQueue(false);

// Speak an utterance while controller is paused. The utterance is queued.
controller()->SpeakOrEnqueue(std::move(utterance));
Expand All @@ -747,7 +747,7 @@ TEST_F(TtsControllerTest, PauseAndStopMustResumeController) {
std::unique_ptr<WebContents> web_contents = CreateWebContents();
std::unique_ptr<TtsUtteranceImpl> utterance =
CreateUtteranceImpl(web_contents.get());
utterance->SetCanEnqueue(true);
utterance->SetShouldClearQueue(false);

// Pause the controller.
controller()->Pause();
Expand Down Expand Up @@ -796,7 +796,7 @@ TEST_F(TtsControllerTest, SpeakWhenLoading) {
std::unique_ptr<WebContents> web_contents = CreateWebContents();
std::unique_ptr<TtsUtteranceImpl> utterance =
CreateUtteranceImpl(web_contents.get());
utterance->SetCanEnqueue(true);
utterance->SetShouldClearQueue(false);

// Speak an utterance while platform is loading, the utterance should be
// queued.
Expand Down
10 changes: 5 additions & 5 deletions content/browser/speech/tts_utterance_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ TtsUtteranceImpl::TtsUtteranceImpl(BrowserContext* browser_context,
was_created_with_web_contents_(web_contents != nullptr),
id_(next_utterance_id_++),
src_id_(-1),
can_enqueue_(false),
should_clear_queue_(true),
char_index_(0),
finished_(false) {
options_.reset(new base::DictionaryValue());
Expand Down Expand Up @@ -155,12 +155,12 @@ TtsUtteranceImpl::GetContinuousParameters() {
return continuous_parameters_;
}

void TtsUtteranceImpl::SetCanEnqueue(bool can_enqueue) {
can_enqueue_ = can_enqueue;
void TtsUtteranceImpl::SetShouldClearQueue(bool value) {
should_clear_queue_ = value;
}

bool TtsUtteranceImpl::GetCanEnqueue() {
return can_enqueue_;
bool TtsUtteranceImpl::GetShouldClearQueue() {
return should_clear_queue_;
}

void TtsUtteranceImpl::SetRequiredEventTypes(
Expand Down
6 changes: 3 additions & 3 deletions content/browser/speech/tts_utterance_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@ class CONTENT_EXPORT TtsUtteranceImpl : public TtsUtterance,
const double volume) override;
const UtteranceContinuousParameters& GetContinuousParameters() override;

void SetCanEnqueue(bool can_enqueue) override;
bool GetCanEnqueue() override;
void SetShouldClearQueue(bool value) override;
bool GetShouldClearQueue() override;

void SetRequiredEventTypes(const std::set<TtsEventType>& types) override;
const std::set<TtsEventType>& GetRequiredEventTypes() override;
Expand Down Expand Up @@ -123,7 +123,7 @@ class CONTENT_EXPORT TtsUtteranceImpl : public TtsUtterance,
std::string voice_name_;
std::string lang_;
UtteranceContinuousParameters continuous_parameters_;
bool can_enqueue_;
bool should_clear_queue_;
std::set<TtsEventType> required_event_types_;
std::set<TtsEventType> desired_event_types_;

Expand Down
9 changes: 5 additions & 4 deletions content/public/browser/tts_controller.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,11 @@ class CONTENT_EXPORT TtsController {
// 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.
// Speak the given utterance. If the utterance's should_flush_queue flag is
// true, clears the speech queue including the currently speaking utterance
// (if one exists), and starts processing the speech queue by speaking the new
// utterance immediately. Otherwise, enqueues the new utterance and triggers
// continued processing of the speech queue.
virtual void SpeakOrEnqueue(std::unique_ptr<TtsUtterance> utterance) = 0;

// Stop all utterances and flush the queue. Implies leaving pause mode
Expand Down
6 changes: 4 additions & 2 deletions content/public/browser/tts_utterance.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,10 @@ class CONTENT_EXPORT TtsUtterance {
const double volume) = 0;
virtual const UtteranceContinuousParameters& GetContinuousParameters() = 0;

virtual void SetCanEnqueue(bool can_enqueue) = 0;
virtual bool GetCanEnqueue() = 0;
// Prior to processing this utterance, determines whether the utterance queue
// gets cleared.
virtual void SetShouldClearQueue(bool value) = 0;
virtual bool GetShouldClearQueue() = 0;

virtual void SetRequiredEventTypes(const std::set<TtsEventType>& types) = 0;
virtual const std::set<TtsEventType>& GetRequiredEventTypes() = 0;
Expand Down

0 comments on commit c06cdad

Please sign in to comment.