Commit a2068243 authored by Etienne Bergeron's avatar Etienne Bergeron Committed by Chromium LUCI CQ

Fix Pause/Resume race issue skipping enqueued utterance

This CL is fixing an inconsistent state that can happen in
the TtsPlatformImplWin class.

TtsPlatformImplWin has a background worker
TtsPlatformImplBackgroundWorkerthat processes
asynchronously tasks and sending back notifications.

There was a corner case where Pause is called
  TtsPlatformImplWin::Pause(...)
and there was a notification in transit to notify the
completion of the current spoke utterance.

This was leading to that state:
  TtsPlatformImplWin::is_speaking_ = false
  TtsPlatformImplWin::paused_ = true

This CL is changing the TtsPlatformImplWin class to handle
properly the notifications sent back by the worker. If the
notifications clear/stop the utterance and the current
state is paused_, a Resume(...) is performed to ensure
a valid state.

R=dmazzoni@chromium.org

Bug: 1167103
Change-Id: I719dca37e08094afc214d469432c7e2541d155f2
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2640753Reviewed-by: default avatarDominic Mazzoni <dmazzoni@chromium.org>
Commit-Queue: Etienne Bergeron <etienneb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#846161}
parent 2d44109e
...@@ -185,6 +185,8 @@ class TtsPlatformImplWin : public TtsPlatformImpl { ...@@ -185,6 +185,8 @@ class TtsPlatformImplWin : public TtsPlatformImpl {
base::OnceCallback<void(bool)> on_speak_finished, base::OnceCallback<void(bool)> on_speak_finished,
const std::string& parsed_utterance); const std::string& parsed_utterance);
void FinishCurrentUtterance();
// These variables hold the platform state. // These variables hold the platform state.
bool paused_ = false; bool paused_ = false;
bool is_speaking_ = false; bool is_speaking_ = false;
...@@ -294,6 +296,16 @@ void TtsPlatformImplBackgroundWorker::ProcessSpeech( ...@@ -294,6 +296,16 @@ void TtsPlatformImplBackgroundWorker::ProcessSpeech(
FROM_HERE, base::BindOnce(std::move(on_speak_finished), success)); FROM_HERE, base::BindOnce(std::move(on_speak_finished), success));
} }
void TtsPlatformImplWin::FinishCurrentUtterance() {
if (paused_)
Resume();
DCHECK(is_speaking_);
DCHECK_NE(utterance_id_, kInvalidUtteranceId);
is_speaking_ = false;
utterance_id_ = kInvalidUtteranceId;
}
void TtsPlatformImplBackgroundWorker::StopSpeaking(bool paused) { void TtsPlatformImplBackgroundWorker::StopSpeaking(bool paused) {
if (speech_synthesizer_.Get()) { if (speech_synthesizer_.Get()) {
// Block notifications from the current utterance. // Block notifications from the current utterance.
...@@ -542,7 +554,7 @@ void TtsPlatformImplWin::Resume() { ...@@ -542,7 +554,7 @@ void TtsPlatformImplWin::Resume() {
DCHECK(BrowserThread::CurrentlyOn(content::BrowserThread::UI)); DCHECK(BrowserThread::CurrentlyOn(content::BrowserThread::UI));
DCHECK(platform_initialized_); DCHECK(platform_initialized_);
if (!paused_ || !is_speaking_) if (!paused_)
return; return;
worker_.Post(FROM_HERE, &TtsPlatformImplBackgroundWorker::Resume); worker_.Post(FROM_HERE, &TtsPlatformImplBackgroundWorker::Resume);
...@@ -586,10 +598,8 @@ void TtsPlatformImplWin::OnSpeakScheduled( ...@@ -586,10 +598,8 @@ void TtsPlatformImplWin::OnSpeakScheduled(
// If the utterance was not able to be emitted, stop the speaking. There // If the utterance was not able to be emitted, stop the speaking. There
// won't be any asynchronous TTS event to confirm the end of the speech. // won't be any asynchronous TTS event to confirm the end of the speech.
if (!success) { if (!success)
is_speaking_ = false; FinishCurrentUtterance();
utterance_id_ = kInvalidUtteranceId;
}
// Pass the results to our caller. // Pass the results to our caller.
std::move(on_speak_finished).Run(success); std::move(on_speak_finished).Run(success);
...@@ -600,10 +610,7 @@ void TtsPlatformImplWin::OnSpeakFinished(int utterance_id) { ...@@ -600,10 +610,7 @@ void TtsPlatformImplWin::OnSpeakFinished(int utterance_id) {
if (utterance_id != utterance_id_) if (utterance_id != utterance_id_)
return; return;
DCHECK(is_speaking_); FinishCurrentUtterance();
DCHECK_NE(utterance_id_, kInvalidUtteranceId);
is_speaking_ = false;
utterance_id_ = kInvalidUtteranceId;
} }
void TtsPlatformImplWin::ProcessSpeech( void TtsPlatformImplWin::ProcessSpeech(
......
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