diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-10-29 10:46:47 +0100 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-11-02 12:02:10 +0000 |
commit | 99677208ff3b216fdfec551fbe548da5520cd6fb (patch) | |
tree | 476a4865c10320249360e859d8fdd3e01833b03a /chromium/content/browser/speech | |
parent | c30a6232df03e1efbd9f3b226777b07e087a1122 (diff) | |
download | qtwebengine-chromium-99677208ff3b216fdfec551fbe548da5520cd6fb.tar.gz |
BASELINE: Update Chromium to 86.0.4240.124
Change-Id: Ide0ff151e94cd665ae6521a446995d34a9d1d644
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/content/browser/speech')
9 files changed, 167 insertions, 57 deletions
diff --git a/chromium/content/browser/speech/speech_recognition_browsertest.cc b/chromium/content/browser/speech/speech_recognition_browsertest.cc index cf1dc5cbf2c..d6be828a8e6 100644 --- a/chromium/content/browser/speech/speech_recognition_browsertest.cc +++ b/chromium/content/browser/speech/speech_recognition_browsertest.cc @@ -298,7 +298,7 @@ IN_PROC_BROWSER_TEST_F(SpeechRecognitionBrowserTest, DISABLED_Precheck) { } // Flaky on mac, see https://crbug.com/794645. -#if defined(OS_MACOSX) +#if defined(OS_MAC) #define MAYBE_OneShotRecognition DISABLED_OneShotRecognition #else #define MAYBE_OneShotRecognition OneShotRecognition diff --git a/chromium/content/browser/speech/speech_recognition_engine_unittest.cc b/chromium/content/browser/speech/speech_recognition_engine_unittest.cc index a68c4165ff5..4515d1a4dbb 100644 --- a/chromium/content/browser/speech/speech_recognition_engine_unittest.cc +++ b/chromium/content/browser/speech/speech_recognition_engine_unittest.cc @@ -22,7 +22,6 @@ #include "net/base/net_errors.h" #include "net/http/http_response_headers.h" #include "net/http/http_util.h" -#include "net/url_request/url_request_context_getter.h" #include "services/network/public/cpp/url_loader_completion_status.h" #include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h" #include "services/network/public/mojom/url_response_head.mojom.h" diff --git a/chromium/content/browser/speech/tts_android.cc b/chromium/content/browser/speech/tts_android.cc index 7dc3e23b001..0cfba530b79 100644 --- a/chromium/content/browser/speech/tts_android.cc +++ b/chromium/content/browser/speech/tts_android.cc @@ -10,9 +10,12 @@ #include "base/bind.h" #include "base/memory/singleton.h" #include "base/strings/utf_string_conversions.h" +#include "content/browser/speech/tts_controller_impl.h" +#include "content/browser/speech/tts_environment_android_impl.h" #include "content/common/buildflags.h" #include "content/public/android/content_jni_headers/TtsPlatformImpl_jni.h" -#include "content/public/browser/tts_controller.h" +#include "content/public/browser/content_browser_client.h" +#include "content/public/common/content_client.h" using base::android::AttachCurrentThread; using base::android::JavaParamRef; @@ -20,6 +23,14 @@ using base::android::JavaParamRef; namespace content { TtsPlatformImplAndroid::TtsPlatformImplAndroid() : utterance_id_(0) { + environment_android_ = + GetContentClient()->browser()->CreateTtsEnvironmentAndroid(); + if (!environment_android_) + environment_android_ = std::make_unique<TtsEnvironmentAndroidImpl>(); + TtsControllerImpl::GetInstance()->SetStopSpeakingWhenHidden( + !environment_android_->CanSpeakUtterancesFromHiddenWebContents()); + environment_android_->SetCanSpeakNowChangedCallback(base::BindRepeating( + &TtsPlatformImplAndroid::OnCanSpeakNowChanged, base::Unretained(this))); JNIEnv* env = AttachCurrentThread(); java_ref_.Reset( Java_TtsPlatformImpl_create(env, reinterpret_cast<intptr_t>(this))); @@ -40,12 +51,13 @@ void TtsPlatformImplAndroid::Speak( const std::string& lang, const VoiceData& voice, const UtteranceContinuousParameters& params, - base::OnceCallback<void(bool)> on_speak_finished) { + base::OnceCallback<void(bool)> did_start_speaking_callback) { // Parse SSML and process speech. TtsController::GetInstance()->StripSSML( - utterance, base::BindOnce(&TtsPlatformImplAndroid::ProcessSpeech, - weak_factory_.GetWeakPtr(), utterance_id, lang, - voice, params, std::move(on_speak_finished))); + utterance, + base::BindOnce(&TtsPlatformImplAndroid::ProcessSpeech, + weak_factory_.GetWeakPtr(), utterance_id, lang, voice, + params, std::move(did_start_speaking_callback))); } void TtsPlatformImplAndroid::ProcessSpeech( @@ -53,22 +65,32 @@ void TtsPlatformImplAndroid::ProcessSpeech( const std::string& lang, const VoiceData& voice, const UtteranceContinuousParameters& params, - base::OnceCallback<void(bool)> on_speak_finished, + base::OnceCallback<void(bool)> did_start_speaking_callback, const std::string& parsed_utterance) { + std::move(did_start_speaking_callback) + .Run(StartSpeakingNow(utterance_id, lang, params, parsed_utterance)); +} + +bool TtsPlatformImplAndroid::StartSpeakingNow( + int utterance_id, + const std::string& lang, + const UtteranceContinuousParameters& params, + const std::string& parsed_utterance) { + if (!environment_android_->CanSpeakNow()) + return false; + JNIEnv* env = AttachCurrentThread(); - jboolean success = Java_TtsPlatformImpl_speak( + const bool did_start = Java_TtsPlatformImpl_speak( env, java_ref_, utterance_id, base::android::ConvertUTF8ToJavaString(env, parsed_utterance), base::android::ConvertUTF8ToJavaString(env, lang), params.rate, params.pitch, params.volume); - if (!success) { - std::move(on_speak_finished).Run(false); - return; - } + if (!did_start) + return false; utterance_ = parsed_utterance; utterance_id_ = utterance_id; - std::move(on_speak_finished).Run(true); + return true; } bool TtsPlatformImplAndroid::StopSpeaking() { @@ -109,31 +131,22 @@ void TtsPlatformImplAndroid::GetVoices(std::vector<VoiceData>* out_voices) { } } -void TtsPlatformImplAndroid::RequestTtsStop(JNIEnv* env, - const JavaParamRef<jobject>& obj) { - TtsController::GetInstance()->Stop(); -} - -void TtsPlatformImplAndroid::VoicesChanged(JNIEnv* env, - const JavaParamRef<jobject>& obj) { +void TtsPlatformImplAndroid::VoicesChanged(JNIEnv* env) { TtsController::GetInstance()->VoicesChanged(); } void TtsPlatformImplAndroid::OnEndEvent(JNIEnv* env, - const JavaParamRef<jobject>& obj, jint utterance_id) { SendFinalTtsEvent(utterance_id, TTS_EVENT_END, static_cast<int>(utterance_.size())); } void TtsPlatformImplAndroid::OnErrorEvent(JNIEnv* env, - const JavaParamRef<jobject>& obj, jint utterance_id) { SendFinalTtsEvent(utterance_id, TTS_EVENT_ERROR, 0); } void TtsPlatformImplAndroid::OnStartEvent(JNIEnv* env, - const JavaParamRef<jobject>& obj, jint utterance_id) { if (utterance_id != utterance_id_) return; @@ -166,4 +179,9 @@ TtsPlatformImpl* TtsPlatformImpl::GetInstance() { return TtsPlatformImplAndroid::GetInstance(); } +void TtsPlatformImplAndroid::OnCanSpeakNowChanged() { + if (!environment_android_->CanSpeakNow()) + TtsController::GetInstance()->Stop(); +} + } // namespace content diff --git a/chromium/content/browser/speech/tts_android.h b/chromium/content/browser/speech/tts_android.h index bb2c05e535a..f7aa88c5162 100644 --- a/chromium/content/browser/speech/tts_android.h +++ b/chromium/content/browser/speech/tts_android.h @@ -5,22 +5,27 @@ #ifndef CONTENT_BROWSER_SPEECH_TTS_ANDROID_H_ #define CONTENT_BROWSER_SPEECH_TTS_ANDROID_H_ +#include <memory> + #include "base/android/scoped_java_ref.h" #include "base/macros.h" #include "content/browser/speech/tts_platform_impl.h" namespace content { +class TtsEnvironmentAndroid; + class TtsPlatformImplAndroid : public TtsPlatformImpl { public: // TtsPlatform overrides. bool PlatformImplAvailable() override; - void Speak(int utterance_id, - const std::string& utterance, - const std::string& lang, - const VoiceData& voice, - const UtteranceContinuousParameters& params, - base::OnceCallback<void(bool)> on_speak_finished) override; + void Speak( + int utterance_id, + const std::string& utterance, + const std::string& lang, + const VoiceData& voice, + const UtteranceContinuousParameters& params, + base::OnceCallback<void(bool)> did_start_speaking_callback) override; bool StopSpeaking() override; void Pause() override; void Resume() override; @@ -28,19 +33,10 @@ class TtsPlatformImplAndroid : public TtsPlatformImpl { void GetVoices(std::vector<VoiceData>* out_voices) override; // Methods called from Java via JNI. - void RequestTtsStop(JNIEnv* env, - const base::android::JavaParamRef<jobject>& obj); - void VoicesChanged(JNIEnv* env, - const base::android::JavaParamRef<jobject>& obj); - void OnEndEvent(JNIEnv* env, - const base::android::JavaParamRef<jobject>& obj, - jint utterance_id); - void OnErrorEvent(JNIEnv* env, - const base::android::JavaParamRef<jobject>& obj, - jint utterance_id); - void OnStartEvent(JNIEnv* env, - const base::android::JavaParamRef<jobject>& obj, - jint utterance_id); + void VoicesChanged(JNIEnv* env); + void OnEndEvent(JNIEnv* env, jint utterance_id); + void OnErrorEvent(JNIEnv* env, jint utterance_id); + void OnStartEvent(JNIEnv* env, jint utterance_id); // Static functions. static TtsPlatformImplAndroid* GetInstance(); @@ -55,16 +51,28 @@ class TtsPlatformImplAndroid : public TtsPlatformImpl { TtsEventType event_type, int char_index); + // Called once TtsController has stripped ssml. void ProcessSpeech(int utterance_id, const std::string& lang, const VoiceData& voice, const UtteranceContinuousParameters& params, - base::OnceCallback<void(bool)> on_speak_finished, + base::OnceCallback<void(bool)> did_start_speaking_callback, const std::string& parsed_utterance); + // Starts speaking the utterance now. Returns true if speech started, false + // if it is not possible to speak now. + bool StartSpeakingNow(int utterance_id, + const std::string& lang, + const UtteranceContinuousParameters& params, + const std::string& parsed_utterance); + + // Called when TtsEnvironmentAndroid::CanSpeakNow() may have changed. + void OnCanSpeakNowChanged(); + base::android::ScopedJavaGlobalRef<jobject> java_ref_; int utterance_id_; std::string utterance_; + std::unique_ptr<TtsEnvironmentAndroid> environment_android_; base::WeakPtrFactory<TtsPlatformImplAndroid> weak_factory_{this}; diff --git a/chromium/content/browser/speech/tts_controller_impl.cc b/chromium/content/browser/speech/tts_controller_impl.cc index e34045ca4e1..2b7bd10feca 100644 --- a/chromium/content/browser/speech/tts_controller_impl.cc +++ b/chromium/content/browser/speech/tts_controller_impl.cc @@ -105,6 +105,10 @@ TtsControllerImpl* TtsControllerImpl::GetInstance() { return base::Singleton<TtsControllerImpl>::get(); } +void TtsControllerImpl::SetStopSpeakingWhenHidden(bool value) { + stop_speaking_when_hidden_ = value; +} + TtsControllerImpl::TtsControllerImpl() = default; TtsControllerImpl::~TtsControllerImpl() { @@ -166,7 +170,7 @@ bool TtsControllerImpl::StopCurrentUtteranceIfMatches(const GURL& source_url) { if (current_utterance_ && !current_utterance_->GetEngineId().empty()) { if (engine_delegate_) engine_delegate_->Stop(current_utterance_.get()); - } else { + } else if (GetTtsPlatform()->PlatformImplAvailable()) { GetTtsPlatform()->ClearError(); GetTtsPlatform()->StopSpeaking(); } @@ -531,10 +535,6 @@ void TtsControllerImpl::UpdateUtteranceDefaults(TtsUtterance* utterance) { utterance->SetContinuousParameters(rate, pitch, volume); } -void TtsControllerImpl::SetStopSpeakingWhenHidden(bool value) { - stop_speaking_when_hidden_ = value; -} - void TtsControllerImpl::StripSSML( const std::string& utterance, base::OnceCallback<void(const std::string&)> on_ssml_parsed) { diff --git a/chromium/content/browser/speech/tts_controller_impl.h b/chromium/content/browser/speech/tts_controller_impl.h index 638c3691d6d..6b1d43277bc 100644 --- a/chromium/content/browser/speech/tts_controller_impl.h +++ b/chromium/content/browser/speech/tts_controller_impl.h @@ -42,6 +42,8 @@ class CONTENT_EXPORT TtsControllerImpl : public TtsController, // Get the single instance of this class. static TtsControllerImpl* GetInstance(); + void SetStopSpeakingWhenHidden(bool value); + // TtsController methods bool IsSpeaking() override; void SpeakOrEnqueue(std::unique_ptr<TtsUtterance> utterance) override; @@ -62,7 +64,6 @@ class CONTENT_EXPORT TtsControllerImpl : public TtsController, void RemoveUtteranceEventDelegate(UtteranceEventDelegate* delegate) override; void SetTtsEngineDelegate(TtsEngineDelegate* delegate) override; TtsEngineDelegate* GetTtsEngineDelegate() override; - void SetStopSpeakingWhenHidden(bool value) override; // Called directly by ~BrowserContext, because a raw BrowserContext pointer // is stored in an Utterance. diff --git a/chromium/content/browser/speech/tts_environment_android_impl.cc b/chromium/content/browser/speech/tts_environment_android_impl.cc new file mode 100644 index 00000000000..88c0338f981 --- /dev/null +++ b/chromium/content/browser/speech/tts_environment_android_impl.cc @@ -0,0 +1,43 @@ +// Copyright 2020 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 "content/browser/speech/tts_environment_android_impl.h" + +#include "base/bind.h" +#include "base/callback.h" + +using base::android::ApplicationStatusListener; + +namespace content { + +TtsEnvironmentAndroidImpl::TtsEnvironmentAndroidImpl() = default; + +TtsEnvironmentAndroidImpl::~TtsEnvironmentAndroidImpl() = default; + +bool TtsEnvironmentAndroidImpl::CanSpeakUtterancesFromHiddenWebContents() { + return true; +} + +bool TtsEnvironmentAndroidImpl::CanSpeakNow() { + return ApplicationStatusListener::HasVisibleActivities(); +} + +void TtsEnvironmentAndroidImpl::SetCanSpeakNowChangedCallback( + base::RepeatingClosure callback) { + if (!application_status_listener_) { + application_status_listener_ = + ApplicationStatusListener::New(base::BindRepeating( + &TtsEnvironmentAndroidImpl::OnApplicationStateChanged, + base::Unretained(this))); + } + can_speak_now_changed_callback_ = std::move(callback); +} + +void TtsEnvironmentAndroidImpl::OnApplicationStateChanged( + base::android::ApplicationState state) { + if (can_speak_now_changed_callback_) + can_speak_now_changed_callback_.Run(); +} + +} // namespace content diff --git a/chromium/content/browser/speech/tts_environment_android_impl.h b/chromium/content/browser/speech/tts_environment_android_impl.h new file mode 100644 index 00000000000..3593342305e --- /dev/null +++ b/chromium/content/browser/speech/tts_environment_android_impl.h @@ -0,0 +1,43 @@ +// Copyright 2020 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 CONTENT_BROWSER_SPEECH_TTS_ENVIRONMENT_ANDROID_IMPL_H_ +#define CONTENT_BROWSER_SPEECH_TTS_ENVIRONMENT_ANDROID_IMPL_H_ + +#include <memory> + +#include "base/android/application_status_listener.h" +#include "base/callback.h" +#include "content/public/browser/tts_environment_android.h" + +namespace content { + +// Default implementation of TtsEnvironment that is used if the embedder +// doesn't supply one. This uses ApplicationStatus to stop speech when the +// application no longer has visible activities and does not allow speech +// if there are no visible activities. +class TtsEnvironmentAndroidImpl : public TtsEnvironmentAndroid { + public: + TtsEnvironmentAndroidImpl(); + TtsEnvironmentAndroidImpl(const TtsEnvironmentAndroidImpl&) = delete; + TtsEnvironmentAndroidImpl& operator=(const TtsEnvironmentAndroidImpl&) = + delete; + ~TtsEnvironmentAndroidImpl() override; + + // TtsEnvironment: + bool CanSpeakUtterancesFromHiddenWebContents() override; + bool CanSpeakNow() override; + void SetCanSpeakNowChangedCallback(base::RepeatingClosure callback) override; + + private: + void OnApplicationStateChanged(base::android::ApplicationState state); + + base::RepeatingClosure can_speak_now_changed_callback_; + std::unique_ptr<base::android::ApplicationStatusListener> + application_status_listener_; +}; + +} // namespace content + +#endif // CONTENT_BROWSER_SPEECH_TTS_ENVIRONMENT_ANDROID_IMPL_H_ diff --git a/chromium/content/browser/speech/tts_win.cc b/chromium/content/browser/speech/tts_win.cc index 816ae508b03..a99e9865e2e 100644 --- a/chromium/content/browser/speech/tts_win.cc +++ b/chromium/content/browser/speech/tts_win.cc @@ -224,8 +224,7 @@ bool TtsPlatformImplWin::IsSpeaking() { void TtsPlatformImplWin::GetVoices(std::vector<VoiceData>* out_voices) { Microsoft::WRL::ComPtr<IEnumSpObjectTokens> voice_tokens; unsigned long voice_count; - if (S_OK != - SpEnumTokens(SPCAT_VOICES, NULL, NULL, voice_tokens.GetAddressOf())) + if (S_OK != SpEnumTokens(SPCAT_VOICES, NULL, NULL, &voice_tokens)) return; if (S_OK != voice_tokens->GetCount(&voice_count)) return; @@ -234,7 +233,7 @@ void TtsPlatformImplWin::GetVoices(std::vector<VoiceData>* out_voices) { VoiceData voice; Microsoft::WRL::ComPtr<ISpObjectToken> voice_token; - if (S_OK != voice_tokens->Next(1, voice_token.GetAddressOf(), NULL)) + if (S_OK != voice_tokens->Next(1, &voice_token, NULL)) return; base::win::ScopedCoMem<WCHAR> description; @@ -243,7 +242,7 @@ void TtsPlatformImplWin::GetVoices(std::vector<VoiceData>* out_voices) { voice.name = base::WideToUTF8(description.get()); Microsoft::WRL::ComPtr<ISpDataKey> attributes; - if (S_OK != voice_token->OpenKey(kAttributesKey, attributes.GetAddressOf())) + if (S_OK != voice_token->OpenKey(kAttributesKey, &attributes)) continue; base::win::ScopedCoMem<WCHAR> language; @@ -314,15 +313,14 @@ void TtsPlatformImplWin::SetVoiceFromName(const std::string& name) { Microsoft::WRL::ComPtr<IEnumSpObjectTokens> voice_tokens; unsigned long voice_count; - if (S_OK != - SpEnumTokens(SPCAT_VOICES, NULL, NULL, voice_tokens.GetAddressOf())) + if (S_OK != SpEnumTokens(SPCAT_VOICES, NULL, NULL, &voice_tokens)) return; if (S_OK != voice_tokens->GetCount(&voice_count)) return; for (unsigned i = 0; i < voice_count; i++) { Microsoft::WRL::ComPtr<ISpObjectToken> voice_token; - if (S_OK != voice_tokens->Next(1, voice_token.GetAddressOf(), NULL)) + if (S_OK != voice_tokens->Next(1, &voice_token, NULL)) return; base::win::ScopedCoMem<WCHAR> description; |