Commit 6ceb3883 authored by Katie D's avatar Katie D Committed by Commit Bot

Use user preferences for TTS speech rate, pitch and volume if not set.

Bug: 823359
Cq-Include-Trybots: master.tryserver.chromium.linux:closure_compilation
Change-Id: I772e1fa78e0f3f7ed3a6ab858f4855f65f18513f
Reviewed-on: https://chromium-review.googlesource.com/1014491
Commit-Queue: Katie Dektar <katie@chromium.org>
Reviewed-by: default avatarJochen Eisinger <jochen@chromium.org>
Reviewed-by: default avatarNico Weber <thakis@chromium.org>
Reviewed-by: default avatarDavid Tseng <dtseng@chromium.org>
Cr-Commit-Position: refs/heads/master@{#552826}
parent 19f1a9f4
......@@ -149,6 +149,7 @@ include_rules = [
"+third_party/blink/public/platform/web_mouse_wheel_event.h",
"+third_party/blink/public/platform/web_referrer_policy.h",
"+third_party/blink/public/platform/web_security_style.h",
"+third_party/blink/public/platform/web_speech_synthesis_constants.h",
"+third_party/blink/public/platform/web_sudden_termination_disabler_type.h",
"+third_party/blink/public/platform/modules/notifications/web_notification_constants.h",
"+third_party/blink/public/platform/modules/remoteplayback/web_remote_playback_availability.h",
......
......@@ -52,6 +52,7 @@
#include "components/user_manager/user.h"
#include "components/user_manager/user_manager.h"
#include "content/public/browser/browser_thread.h"
#include "third_party/blink/public/platform/web_speech_synthesis_constants.h"
#include "third_party/cros_system_api/dbus/update_engine/dbus-constants.h"
#include "third_party/icu/source/i18n/unicode/timezone.h"
#include "ui/base/ime/chromeos/extension_ime_util.h"
......@@ -419,13 +420,16 @@ void Preferences::RegisterProfilePrefs(
prefs::kTextToSpeechLangToVoiceName,
user_prefs::PrefRegistrySyncable::SYNCABLE_PREF | PrefRegistry::PUBLIC);
registry->RegisterDoublePref(
prefs::kTextToSpeechRate, 1.0,
prefs::kTextToSpeechRate,
blink::SpeechSynthesisConstants::kDefaultTextToSpeechRate,
user_prefs::PrefRegistrySyncable::SYNCABLE_PREF | PrefRegistry::PUBLIC);
registry->RegisterDoublePref(
prefs::kTextToSpeechPitch, 1.0,
prefs::kTextToSpeechPitch,
blink::SpeechSynthesisConstants::kDefaultTextToSpeechPitch,
user_prefs::PrefRegistrySyncable::SYNCABLE_PREF | PrefRegistry::PUBLIC);
registry->RegisterDoublePref(
prefs::kTextToSpeechVolume, 1.0,
prefs::kTextToSpeechVolume,
blink::SpeechSynthesisConstants::kDefaultTextToSpeechVolume,
user_prefs::PrefRegistrySyncable::SYNCABLE_PREF | PrefRegistry::PUBLIC);
}
......
......@@ -19,6 +19,7 @@
#include "chrome/browser/speech/tts_controller.h"
#include "extensions/browser/event_router.h"
#include "extensions/browser/extension_function_registry.h"
#include "third_party/blink/public/platform/web_speech_synthesis_constants.h"
#include "ui/base/l10n/l10n_util.h"
namespace constants = tts_extension_api_constants;
......@@ -195,7 +196,7 @@ bool TtsSpeakFunction::RunAsync() {
return false;
}
double rate = 1.0;
double rate = blink::SpeechSynthesisConstants::kDoublePrefNotSet;
if (options->HasKey(constants::kRateKey)) {
EXTENSION_FUNCTION_VALIDATE(
options->GetDouble(constants::kRateKey, &rate));
......@@ -205,7 +206,7 @@ bool TtsSpeakFunction::RunAsync() {
}
}
double pitch = 1.0;
double pitch = blink::SpeechSynthesisConstants::kDoublePrefNotSet;
if (options->HasKey(constants::kPitchKey)) {
EXTENSION_FUNCTION_VALIDATE(
options->GetDouble(constants::kPitchKey, &pitch));
......@@ -215,7 +216,7 @@ bool TtsSpeakFunction::RunAsync() {
}
}
double volume = 1.0;
double volume = blink::SpeechSynthesisConstants::kDoublePrefNotSet;
if (options->HasKey(constants::kVolumeKey)) {
EXTENSION_FUNCTION_VALIDATE(
options->GetDouble(constants::kVolumeKey, &volume));
......
......@@ -15,7 +15,11 @@
#include "base/values.h"
#include "build/build_config.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/speech/tts_platform.h"
#include "chrome/common/pref_names.h"
#include "components/prefs/pref_service.h"
#include "third_party/blink/public/platform/web_speech_synthesis_constants.h"
namespace {
// A value to be used to indicate that there is no char index available.
......@@ -63,12 +67,10 @@ bool IsFinalTtsEventType(TtsEventType event_type) {
// UtteranceContinuousParameters
//
UtteranceContinuousParameters::UtteranceContinuousParameters()
: rate(-1),
pitch(-1),
volume(-1) {}
: rate(blink::SpeechSynthesisConstants::kDoublePrefNotSet),
pitch(blink::SpeechSynthesisConstants::kDoublePrefNotSet),
volume(blink::SpeechSynthesisConstants::kDoublePrefNotSet) {}
//
// VoiceData
......@@ -120,7 +122,7 @@ void Utterance::OnTtsEvent(TtsEventType event_type,
if (event_delegate_)
event_delegate_->OnTtsEvent(this, event_type, char_index, error_message);
if (finished_)
event_delegate_ = NULL;
event_delegate_ = nullptr;
}
void Utterance::Finish() {
......@@ -145,11 +147,11 @@ TtsControllerImpl* TtsControllerImpl::GetInstance() {
}
TtsControllerImpl::TtsControllerImpl()
: current_utterance_(NULL),
: current_utterance_(nullptr),
paused_(false),
platform_impl_(NULL),
tts_engine_delegate_(NULL) {
}
platform_impl_(nullptr),
tts_engine_delegate_(nullptr),
pref_service_for_testing_(nullptr) {}
TtsControllerImpl::~TtsControllerImpl() {
if (current_utterance_) {
......@@ -196,7 +198,9 @@ void TtsControllerImpl::SpeakNow(Utterance* utterance) {
if (index >= 0)
voice = voices[index];
else
voice.native = true; // Try to let
voice.native = true;
UpdateUtteranceDefaults(utterance);
GetPlatformImpl()->WillSpeakUtteranceWithVoice(utterance, voice);
......@@ -231,7 +235,7 @@ void TtsControllerImpl::SpeakNow(Utterance* utterance) {
if (!sends_end_event) {
utterance->Finish();
delete utterance;
current_utterance_ = NULL;
current_utterance_ = nullptr;
SpeakNextUtterance();
}
#endif
......@@ -247,7 +251,7 @@ void TtsControllerImpl::SpeakNow(Utterance* utterance) {
voice,
utterance->continuous_parameters());
if (!success)
current_utterance_ = NULL;
current_utterance_ = nullptr;
// If the native voice wasn't able to process this speech, see if
// the browser has built-in TTS that isn't loaded yet.
......@@ -386,7 +390,7 @@ void TtsControllerImpl::GetVoices(content::BrowserContext* browser_context,
}
bool TtsControllerImpl::IsSpeaking() {
return current_utterance_ != NULL || GetPlatformImpl()->IsSpeaking();
return current_utterance_ != nullptr || GetPlatformImpl()->IsSpeaking();
}
void TtsControllerImpl::FinishCurrentUtterance() {
......@@ -395,7 +399,7 @@ void TtsControllerImpl::FinishCurrentUtterance() {
current_utterance_->OnTtsEvent(TTS_EVENT_INTERRUPTED, kInvalidCharIndex,
std::string());
delete current_utterance_;
current_utterance_ = NULL;
current_utterance_ = nullptr;
}
}
......@@ -532,6 +536,49 @@ int TtsControllerImpl::GetMatchingVoice(
return best_score_index;
}
void TtsControllerImpl::UpdateUtteranceDefaults(Utterance* utterance) {
double rate = utterance->continuous_parameters().rate;
double pitch = utterance->continuous_parameters().pitch;
double volume = utterance->continuous_parameters().volume;
#if defined(OS_CHROMEOS)
// Update pitch, rate and volume from user prefs if not set explicitly
// on this utterance.
const PrefService* prefs = nullptr;
// The utterance->browser_context() is null in tests.
if (utterance->browser_context()) {
const Profile* profile =
Profile::FromBrowserContext(utterance->browser_context());
if (profile)
prefs = profile->GetPrefs();
} else if (pref_service_for_testing_) {
prefs = pref_service_for_testing_;
}
if (rate == blink::SpeechSynthesisConstants::kDoublePrefNotSet) {
rate = prefs ? prefs->GetDouble(prefs::kTextToSpeechRate)
: blink::SpeechSynthesisConstants::kDefaultTextToSpeechRate;
}
if (pitch == blink::SpeechSynthesisConstants::kDoublePrefNotSet) {
pitch = prefs ? prefs->GetDouble(prefs::kTextToSpeechPitch)
: blink::SpeechSynthesisConstants::kDefaultTextToSpeechPitch;
}
if (volume == blink::SpeechSynthesisConstants::kDoublePrefNotSet) {
volume = prefs
? prefs->GetDouble(prefs::kTextToSpeechVolume)
: blink::SpeechSynthesisConstants::kDefaultTextToSpeechVolume;
}
#else
// Update pitch, rate and volume to defaults if not explicity set on
// this utterance.
if (rate == blink::SpeechSynthesisConstants::kDoublePrefNotSet)
rate = blink::SpeechSynthesisConstants::kDefaultTextToSpeechRate;
if (pitch == blink::SpeechSynthesisConstants::kDoublePrefNotSet)
pitch = blink::SpeechSynthesisConstants::kDefaultTextToSpeechPitch;
if (volume == blink::SpeechSynthesisConstants::kDoublePrefNotSet)
volume = blink::SpeechSynthesisConstants::kDefaultTextToSpeechVolume;
#endif // defined(OS_CHROMEOS)
utterance->set_continuous_parameters(rate, pitch, volume);
}
void TtsControllerImpl::VoicesChanged() {
// Existence of platform tts indicates explicit requests to tts. Since
// |VoicesChanged| can occur implicitly, only send if needed.
......@@ -570,7 +617,7 @@ void TtsControllerImpl::RemoveUtteranceEventDelegate(
}
if (current_utterance_ && current_utterance_->event_delegate() == delegate) {
current_utterance_->set_event_delegate(NULL);
current_utterance_->set_event_delegate(nullptr);
if (!current_utterance_->extension_id().empty()) {
if (tts_engine_delegate_)
tts_engine_delegate_->Stop(current_utterance_);
......
......@@ -15,6 +15,7 @@
#include "base/macros.h"
#include "base/memory/singleton.h"
#include "chrome/browser/speech/tts_controller.h"
#include "components/prefs/testing_pref_service.h"
#include "url/gurl.h"
namespace content {
......@@ -56,6 +57,8 @@ class TtsControllerImpl : public TtsController {
private:
FRIEND_TEST_ALL_PREFIXES(TtsControllerTest, TestGetMatchingVoice);
FRIEND_TEST_ALL_PREFIXES(TtsControllerTest,
TestTtsControllerUtteranceDefaults);
// Get the platform TTS implementation (or injected mock).
TtsPlatformImpl* GetPlatformImpl();
......@@ -79,6 +82,11 @@ class TtsControllerImpl : public TtsController {
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);
friend struct base::DefaultSingletonTraits<TtsControllerImpl>;
// The current utterance being spoken.
......@@ -100,6 +108,9 @@ class TtsControllerImpl : public TtsController {
// The delegate that processes TTS requests with user-installed extensions.
TtsEngineDelegate* tts_engine_delegate_;
// A mock pref service that should be used for testing only.
PrefService* pref_service_for_testing_;
DISALLOW_COPY_AND_ASSIGN(TtsControllerImpl);
};
......
......@@ -7,7 +7,11 @@
#include "base/values.h"
#include "chrome/browser/speech/tts_controller_impl.h"
#include "chrome/browser/speech/tts_platform.h"
#include "chrome/common/pref_names.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"
class TtsControllerTest : public testing::Test {
};
......@@ -48,12 +52,12 @@ TEST_F(TtsControllerTest, TestTtsControllerShutdown) {
new TestableTtsController();
controller->SetPlatformImpl(&platform_impl);
Utterance* utterance1 = new Utterance(NULL);
Utterance* utterance1 = new Utterance(nullptr);
utterance1->set_can_enqueue(true);
utterance1->set_src_id(1);
controller->SpeakOrEnqueue(utterance1);
Utterance* utterance2 = new Utterance(NULL);
Utterance* utterance2 = new Utterance(nullptr);
utterance2->set_can_enqueue(true);
utterance2->set_src_id(2);
controller->SpeakOrEnqueue(utterance2);
......@@ -67,7 +71,7 @@ TEST_F(TtsControllerTest, TestGetMatchingVoice) {
TtsControllerImpl* tts_controller = TtsControllerImpl::GetInstance();
{
// Calling GetMatchingVoice with no voices returns -1
// Calling GetMatchingVoice with no voices returns -1.
Utterance utterance(nullptr);
std::vector<VoiceData> voices;
EXPECT_EQ(-1, tts_controller->GetMatchingVoice(&utterance, voices));
......@@ -149,3 +153,41 @@ TEST_F(TtsControllerTest, TestGetMatchingVoice) {
EXPECT_EQ(6, tts_controller->GetMatchingVoice(&utterance, voices));
}
}
#if defined(OS_CHROMEOS)
TEST_F(TtsControllerTest, TestTtsControllerUtteranceDefaults) {
TestableTtsController* controller = new TestableTtsController();
Utterance* utterance1 = new Utterance(nullptr);
// Initialized to default (unset constant) values.
EXPECT_EQ(blink::SpeechSynthesisConstants::kDoublePrefNotSet,
utterance1->continuous_parameters().rate);
EXPECT_EQ(blink::SpeechSynthesisConstants::kDoublePrefNotSet,
utterance1->continuous_parameters().pitch);
EXPECT_EQ(blink::SpeechSynthesisConstants::kDoublePrefNotSet,
utterance1->continuous_parameters().volume);
controller->UpdateUtteranceDefaults(utterance1);
// Updated to global defaults.
EXPECT_EQ(blink::SpeechSynthesisConstants::kDefaultTextToSpeechRate,
utterance1->continuous_parameters().rate);
EXPECT_EQ(blink::SpeechSynthesisConstants::kDefaultTextToSpeechPitch,
utterance1->continuous_parameters().pitch);
EXPECT_EQ(blink::SpeechSynthesisConstants::kDefaultTextToSpeechVolume,
utterance1->continuous_parameters().volume);
// Now we will set prefs and expect those to be used as defaults.
TestingPrefServiceSimple pref_service_;
pref_service_.registry()->RegisterDoublePref(prefs::kTextToSpeechRate, 1.5);
pref_service_.registry()->RegisterDoublePref(prefs::kTextToSpeechPitch, 2.0);
pref_service_.registry()->RegisterDoublePref(prefs::kTextToSpeechVolume, 0.5);
controller->pref_service_for_testing_ = &pref_service_;
Utterance* utterance2 = new Utterance(nullptr);
controller->UpdateUtteranceDefaults(utterance2);
// Updated to pref values.
EXPECT_EQ(1.5f, utterance2->continuous_parameters().rate);
EXPECT_EQ(2.0f, utterance2->continuous_parameters().pitch);
EXPECT_EQ(0.5f, utterance2->continuous_parameters().volume);
}
#endif // defined(OS_CHROMEOS)
// 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 THIRD_PARTY_BLINK_PUBLIC_PLATFORM_WEB_SPEECH_SYNTHESIS_CONSTANTS_H_
#define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_WEB_SPEECH_SYNTHESIS_CONSTANTS_H_
namespace blink {
// Constants used in Text-to-Speech.
namespace SpeechSynthesisConstants {
const double kDefaultTextToSpeechRate = 1.0;
const double kDefaultTextToSpeechPitch = 1.0;
const double kDefaultTextToSpeechVolume = 1.0;
const double kDoublePrefNotSet = -1.0;
} // namespace SpeechSynthesisConstants
} // namespace blink
#endif // THIRD_PARTY_BLINK_PUBLIC_PLATFORM_WEB_SPEECH_SYNTHESIS_CONSTANTS_H_
......@@ -34,7 +34,7 @@ PlatformSpeechSynthesisUtterance* PlatformSpeechSynthesisUtterance::Create(
PlatformSpeechSynthesisUtterance::PlatformSpeechSynthesisUtterance(
PlatformSpeechSynthesisUtteranceClient* client)
: client_(client), volume_(1.0f), rate_(1.0f), pitch_(1.0f) {}
: client_(client) {}
void PlatformSpeechSynthesisUtterance::Trace(blink::Visitor* visitor) {
visitor->Trace(client_);
......
......@@ -26,6 +26,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SPEECH_PLATFORM_SPEECH_SYNTHESIS_UTTERANCE_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SPEECH_PLATFORM_SPEECH_SYNTHESIS_UTTERANCE_H_
#include "third_party/blink/public/platform/web_speech_synthesis_constants.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/speech/platform_speech_synthesis_voice.h"
......@@ -83,9 +84,9 @@ class PLATFORM_EXPORT PlatformSpeechSynthesisUtterance final
String text_;
String lang_;
scoped_refptr<PlatformSpeechSynthesisVoice> voice_;
float volume_;
float rate_;
float pitch_;
float volume_ = SpeechSynthesisConstants::kDoublePrefNotSet;
float rate_ = SpeechSynthesisConstants::kDoublePrefNotSet;
float pitch_ = SpeechSynthesisConstants::kDoublePrefNotSet;
double start_time_;
};
......
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