Browse Source

refactor: move text-to-speech out of chromium_src (#15024)

* chore: add tts patch and buildflag, makes tts work again

* chore: add tts patch and buildflag, makes tts work again

* fix: make things compile

* build: add relevant tts files for linux

* fix: update patch and patch description, should now compile on mac

* build: move chrome specific sources under chromium_src:chrome target

* build: enable_extensions again

We are depending on them, check `//electron/chromium_src:chrome` target
for more info.

* fix: update tts.patch to receive notifications about browser context destruction

* fix: extend browser process from chrome layer

The global state g_browser_process is shared between //chrome
and //electron.

* spec: add basic speech synthesis test

* spec: skip speech tests on ci

* build: fix compilation on windows
Heilig Benedek 6 years ago
parent
commit
95696c9456
39 changed files with 625 additions and 3139 deletions
  1. 1 20
      BUILD.gn
  2. 6 1
      atom/browser/api/atom_api_app.cc
  3. 8 2
      atom/browser/atom_browser_client.cc
  4. 6 0
      atom/browser/atom_browser_context.cc
  5. 2 2
      atom/browser/atom_browser_main_parts.cc
  6. 1 1
      atom/browser/atom_browser_main_parts.h
  7. 5 0
      atom/common/api/features.cc
  8. 0 1
      atom/common/common_message_generator.h
  9. 8 1
      atom/renderer/renderer_client_base.cc
  10. 0 1
      build/args/all.gn
  11. 1 0
      buildflags/BUILD.gn
  12. 2 0
      buildflags/buildflags.gni
  13. 43 10
      chromium_src/BUILD.gn
  14. 0 31
      chromium_src/chrome/browser/browser_process.cc
  15. 0 43
      chromium_src/chrome/browser/browser_process.h
  16. 217 0
      chromium_src/chrome/browser/browser_process_impl.cc
  17. 107 0
      chromium_src/chrome/browser/browser_process_impl.h
  18. 0 336
      chromium_src/chrome/browser/speech/tts_controller.h
  19. 0 447
      chromium_src/chrome/browser/speech/tts_controller_impl.cc
  20. 0 102
      chromium_src/chrome/browser/speech/tts_controller_impl.h
  21. 0 349
      chromium_src/chrome/browser/speech/tts_linux.cc
  22. 0 344
      chromium_src/chrome/browser/speech/tts_mac.mm
  23. 0 176
      chromium_src/chrome/browser/speech/tts_message_filter.cc
  24. 0 62
      chromium_src/chrome/browser/speech/tts_message_filter.h
  25. 0 28
      chromium_src/chrome/browser/speech/tts_platform.cc
  26. 0 80
      chromium_src/chrome/browser/speech/tts_platform.h
  27. 0 311
      chromium_src/chrome/browser/speech/tts_win.cc
  28. 0 61
      chromium_src/chrome/common/tts_messages.h
  29. 0 20
      chromium_src/chrome/common/tts_utterance_request.cc
  30. 0 45
      chromium_src/chrome/common/tts_utterance_request.h
  31. 0 198
      chromium_src/chrome/renderer/tts_dispatcher.cc
  32. 0 73
      chromium_src/chrome/renderer/tts_dispatcher.h
  33. 0 52
      chromium_src/library_loaders/libspeechd.h
  34. 0 252
      chromium_src/library_loaders/libspeechd_loader.cc
  35. 2 19
      filenames.gni
  36. 10 6
      patches/common/chromium/.patches.yaml
  37. 0 65
      patches/common/chromium/disable_extensions_gn.patch
  38. 164 0
      patches/common/chromium/tts.patch
  39. 42 0
      spec/chromium-spec.js

+ 1 - 20
BUILD.gn

@@ -8,7 +8,6 @@ import("//build/config/win/manifest.gni")
 import("//pdf/features.gni")
 import("//services/service_manager/public/service_manifest.gni")
 import("//third_party/ffmpeg/ffmpeg_options.gni")
-import("//third_party/widevine/cdm/widevine.gni")
 import("//tools/grit/grit_rule.gni")
 import("//tools/grit/repack.gni")
 import("//tools/v8_context_snapshot/v8_context_snapshot.gni")
@@ -295,15 +294,7 @@ static_library("electron_lib") {
   sources = filenames.lib_sources
   set_sources_assignment_filter(sources_assignment_filter)
 
-  sources += [
-    "$target_gen_dir/atom_natives.h",
-    "//extensions/browser/app_window/size_constraints.cc",
-    "//extensions/browser/app_window/size_constraints.h",
-    "//extensions/common/constants.cc",
-    "//extensions/common/constants.h",
-    "//extensions/common/url_pattern.cc",
-    "//extensions/common/url_pattern.h",
-  ]
+  sources += [ "$target_gen_dir/atom_natives.h" ]
 
   if (is_component_build) {
     defines += [ "NODE_SHARED_MODE" ]
@@ -440,16 +431,6 @@ static_library("electron_lib") {
   if (enable_pepper_flash) {
     deps += [ "components/pepper_flash" ]
   }
-
-  if (enable_widevine) {
-    sources += [
-      "//chrome/renderer/media/chrome_key_systems.cc",
-      "//chrome/renderer/media/chrome_key_systems.h",
-      "//chrome/renderer/media/chrome_key_systems_provider.cc",
-      "//chrome/renderer/media/chrome_key_systems_provider.h",
-    ]
-    deps += [ "//components/cdm/renderer" ]
-  }
 }
 
 electron_paks("packed_resources") {

+ 6 - 1
atom/browser/api/atom_api_app.cc

@@ -23,7 +23,6 @@
 #include "atom/common/native_mate_converters/net_converter.h"
 #include "atom/common/native_mate_converters/network_converter.h"
 #include "atom/common/native_mate_converters/value_converter.h"
-#include "atom/common/node_includes.h"
 #include "atom/common/options_switches.h"
 #include "base/command_line.h"
 #include "base/environment.h"
@@ -54,6 +53,12 @@
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/gfx/image/image.h"
 
+// clang-format off
+// This header should be declared at the end to avoid
+// redefinition errors.
+#include "atom/common/node_includes.h"  // NOLINT(build/include_alpha)
+// clang-format on
+
 #if defined(OS_WIN)
 #include "atom/browser/ui/win/jump_list.h"
 #include "base/strings/utf_string_conversions.h"

+ 8 - 2
atom/browser/atom_browser_client.cc

@@ -40,7 +40,6 @@
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/printing/printing_message_filter.h"
-#include "chrome/browser/speech/tts_message_filter.h"
 #include "components/net_log/chrome_net_log.h"
 #include "content/public/browser/browser_ppapi_host.h"
 #include "content/public/browser/client_certificate_delegate.h"
@@ -85,6 +84,10 @@
 #include "atom/browser/fake_location_provider.h"
 #endif  // BUILDFLAG(OVERRIDE_LOCATION_PROVIDER)
 
+#if BUILDFLAG(ENABLE_TTS)
+#include "chrome/browser/speech/tts_message_filter.h"
+#endif  // BUILDFLAG(ENABLE_TTS)
+
 using content::BrowserThread;
 
 namespace atom {
@@ -207,7 +210,10 @@ void AtomBrowserClient::RenderProcessWillLaunch(
     return;
 
   host->AddFilter(new printing::PrintingMessageFilter(process_id));
-  host->AddFilter(new TtsMessageFilter(process_id, host->GetBrowserContext()));
+
+#if BUILDFLAG(ENABLE_TTS)
+  host->AddFilter(new TtsMessageFilter(host->GetBrowserContext()));
+#endif
 
   ProcessPreferences prefs;
   auto* web_preferences =

+ 6 - 0
atom/browser/atom_browser_context.cc

@@ -32,6 +32,7 @@
 #include "brightray/common/application_info.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/pref_names.h"
+#include "components/keyed_service/content/browser_context_dependency_manager.h"
 #include "components/prefs/json_pref_store.h"
 #include "components/prefs/pref_registry_simple.h"
 #include "components/prefs/pref_service.h"
@@ -119,6 +120,8 @@ AtomBrowserContext::AtomBrowserContext(const std::string& partition,
   proxy_config_monitor_ = std::make_unique<ProxyConfigMonitor>(prefs_.get());
   io_handle_ = new URLRequestContextGetter::Handle(weak_factory_.GetWeakPtr());
   cookie_change_notifier_ = std::make_unique<CookieChangeNotifier>(this);
+
+  BrowserContextDependencyManager::GetInstance()->MarkBrowserContextLive(this);
 }
 
 AtomBrowserContext::~AtomBrowserContext() {
@@ -126,6 +129,9 @@ AtomBrowserContext::~AtomBrowserContext() {
   NotifyWillBeDestroyed(this);
   ShutdownStoragePartitions();
   io_handle_->ShutdownOnUIThread();
+  // Notify any keyed services of browser context destruction.
+  BrowserContextDependencyManager::GetInstance()->DestroyBrowserContextServices(
+      this);
 }
 
 void AtomBrowserContext::InitPrefs() {

+ 2 - 2
atom/browser/atom_browser_main_parts.cc

@@ -19,7 +19,7 @@
 #include "atom/common/node_bindings.h"
 #include "base/command_line.h"
 #include "base/threading/thread_task_runner_handle.h"
-#include "chrome/browser/browser_process.h"
+#include "chrome/browser/browser_process_impl.h"
 #include "chrome/browser/icon_manager.h"
 #include "chrome/browser/net/chrome_net_log_helper.h"
 #include "components/net_log/chrome_net_log.h"
@@ -68,7 +68,7 @@ AtomBrowserMainParts* AtomBrowserMainParts::self_ = nullptr;
 
 AtomBrowserMainParts::AtomBrowserMainParts(
     const content::MainFunctionParams& params)
-    : fake_browser_process_(new BrowserProcess),
+    : fake_browser_process_(new BrowserProcessImpl),
       browser_(new Browser),
       node_bindings_(NodeBindings::Create(NodeBindings::BROWSER)),
       atom_bindings_(new AtomBindings(uv_default_loop())),

+ 1 - 1
atom/browser/atom_browser_main_parts.h

@@ -107,7 +107,7 @@ class AtomBrowserMainParts : public brightray::BrowserMainParts {
 #endif
 
   // A fake BrowserProcess object that used to feed the source code from chrome.
-  std::unique_ptr<BrowserProcess> fake_browser_process_;
+  std::unique_ptr<BrowserProcessImpl> fake_browser_process_;
 
   // Pointer to exit code.
   int* exit_code_ = nullptr;

+ 5 - 0
atom/common/api/features.cc

@@ -30,6 +30,10 @@ bool IsViewApiEnabled() {
   return BUILDFLAG(ENABLE_VIEW_API);
 }
 
+bool IsTtsEnabled() {
+  return BUILDFLAG(ENABLE_TTS);
+}
+
 void Initialize(v8::Local<v8::Object> exports,
                 v8::Local<v8::Value> unused,
                 v8::Local<v8::Context> context,
@@ -41,6 +45,7 @@ void Initialize(v8::Local<v8::Object> exports,
   dict.SetMethod("isFakeLocationProviderEnabled",
                  &IsFakeLocationProviderEnabled);
   dict.SetMethod("isViewApiEnabled", &IsViewApiEnabled);
+  dict.SetMethod("isTtsEnabled", &IsTtsEnabled);
 }
 
 }  // namespace

+ 0 - 1
atom/common/common_message_generator.h

@@ -7,4 +7,3 @@
 #include "atom/common/api/api_messages.h"
 #include "chrome/common/chrome_utility_printing_messages.h"
 #include "chrome/common/print_messages.h"
-#include "chrome/common/tts_messages.h"

+ 8 - 1
atom/renderer/renderer_client_base.cc

@@ -20,7 +20,6 @@
 #include "base/strings/string_split.h"
 #include "base/strings/stringprintf.h"
 #include "chrome/renderer/printing/print_web_view_helper.h"
-#include "chrome/renderer/tts_dispatcher.h"
 #include "content/public/common/content_constants.h"
 #include "content/public/common/content_switches.h"
 #include "content/public/renderer/render_frame.h"
@@ -51,6 +50,10 @@
 #include "chrome/renderer/pepper/pepper_helper.h"
 #endif  // BUILDFLAG(ENABLE_PEPPER_FLASH)
 
+#if BUILDFLAG(ENABLE_TTS)
+#include "chrome/renderer/tts_dispatcher.h"
+#endif  // BUILDFLAG(ENABLE_TTS)
+
 namespace atom {
 
 namespace {
@@ -204,7 +207,11 @@ void RendererClientBase::DidClearWindowObject(
 std::unique_ptr<blink::WebSpeechSynthesizer>
 RendererClientBase::OverrideSpeechSynthesizer(
     blink::WebSpeechSynthesizerClient* client) {
+#if BUILDFLAG(ENABLE_TTS)
   return std::make_unique<TtsDispatcher>(client);
+#else
+  return nullptr;
+#endif
 }
 
 bool RendererClientBase::OverrideCreatePlugin(

+ 0 - 1
build/args/all.gn

@@ -6,7 +6,6 @@ v8_promise_internal_field_count = 1
 v8_typed_array_max_size_in_heap = 0
 
 enable_cdm_host_verification = false
-enable_extensions = false
 proprietary_codecs = true
 ffmpeg_branding = "Chrome"
 

+ 1 - 0
buildflags/BUILD.gn

@@ -15,6 +15,7 @@ buildflag_header("buildflags") {
     "ENABLE_VIEW_API=$enable_view_api",
     "ENABLE_PEPPER_FLASH=$enable_pepper_flash",
     "ENABLE_PDF_VIEWER=$enable_pdf_viewer",
+    "ENABLE_TTS=$enable_tts",
     "OVERRIDE_LOCATION_PROVIDER=$enable_fake_location_provider",
   ]
 }

+ 2 - 0
buildflags/buildflags.gni

@@ -14,6 +14,8 @@ declare_args() {
 
   enable_pdf_viewer = false
 
+  enable_tts = true
+
   # Provide a fake location provider for mocking
   # the geolocation responses. Disable it if you
   # need to test with chromium's location provider.

+ 43 - 10
chromium_src/BUILD.gn

@@ -3,12 +3,14 @@
 # found in the LICENSE file.
 
 import("//electron/buildflags/buildflags.gni")
+import("//third_party/widevine/cdm/widevine.gni")
 
-# Builds some of the chrome sources that Electron depends
-# on unconditionally.
-source_set("chrome") {
+# Builds some of the chrome sources that Electron depends on.
+static_library("chrome") {
   visibility = [ "//electron:electron_lib" ]
   sources = [
+    "//chrome/browser/browser_process.cc",
+    "//chrome/browser/browser_process.h",
     "//chrome/browser/extensions/global_shortcut_listener.cc",
     "//chrome/browser/extensions/global_shortcut_listener.h",
     "//chrome/browser/extensions/global_shortcut_listener_mac.h",
@@ -31,18 +33,15 @@ source_set("chrome") {
     "//chrome/browser/net/proxy_service_factory.h",
     "//chrome/browser/ssl/security_state_tab_helper.cc",
     "//chrome/browser/ssl/security_state_tab_helper.h",
-    "//chrome/common/chrome_constants.cc",
-    "//chrome/common/chrome_constants.h",
-    "//chrome/common/chrome_switches.cc",
-    "//chrome/common/chrome_switches.h",
-    "//chrome/common/secure_origin_whitelist.cc",
-    "//chrome/common/secure_origin_whitelist.h",
+    "//extensions/browser/app_window/size_constraints.cc",
+    "//extensions/browser/app_window/size_constraints.h",
   ]
   public_deps = [
     "//content/public/browser",
   ]
   deps = [
-    "//chrome/common:constants",
+    "//chrome/common",
+    "//components/keyed_service/content",
     "//components/proxy_config",
     "//components/security_state/content",
   ]
@@ -66,4 +65,38 @@ source_set("chrome") {
     ]
     deps += [ "//ui/snapshot" ]
   }
+
+  if (enable_tts) {
+    sources += [
+      "//chrome/browser/speech/tts_controller.h",
+      "//chrome/browser/speech/tts_controller_impl.cc",
+      "//chrome/browser/speech/tts_controller_impl.h",
+      "//chrome/browser/speech/tts_mac.mm",
+      "//chrome/browser/speech/tts_message_filter.cc",
+      "//chrome/browser/speech/tts_message_filter.h",
+      "//chrome/browser/speech/tts_platform.cc",
+      "//chrome/browser/speech/tts_platform.h",
+      "//chrome/browser/speech/tts_win.cc",
+      "//chrome/common/tts_messages.h",
+      "//chrome/common/tts_utterance_request.cc",
+      "//chrome/common/tts_utterance_request.h",
+      "//chrome/renderer/tts_dispatcher.cc",
+      "//chrome/renderer/tts_dispatcher.h",
+    ]
+
+    if (is_linux) {
+      sources += [ "//chrome/browser/speech/tts_linux.cc" ]
+      deps += [ "//third_party/speech-dispatcher" ]
+    }
+  }
+
+  if (enable_widevine) {
+    sources += [
+      "//chrome/renderer/media/chrome_key_systems.cc",
+      "//chrome/renderer/media/chrome_key_systems.h",
+      "//chrome/renderer/media/chrome_key_systems_provider.cc",
+      "//chrome/renderer/media/chrome_key_systems_provider.h",
+    ]
+    deps += [ "//components/cdm/renderer" ]
+  }
 }

+ 0 - 31
chromium_src/chrome/browser/browser_process.cc

@@ -1,31 +0,0 @@
-// Copyright (c) 2012 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 "chrome/browser/browser_process.h"
-
-#include "chrome/browser/printing/print_job_manager.h"
-#include "ui/base/l10n/l10n_util.h"
-
-BrowserProcess* g_browser_process = NULL;
-
-BrowserProcess::BrowserProcess()
-    : print_job_manager_(new printing::PrintJobManager) {
-  g_browser_process = this;
-}
-
-BrowserProcess::~BrowserProcess() {
-  g_browser_process = NULL;
-}
-
-void BrowserProcess::SetApplicationLocale(const std::string& locale) {
-  locale_ = locale;
-}
-
-std::string BrowserProcess::GetApplicationLocale() {
-  return locale_;
-}
-
-printing::PrintJobManager* BrowserProcess::print_job_manager() {
-  return print_job_manager_.get();
-}

+ 0 - 43
chromium_src/chrome/browser/browser_process.h

@@ -1,43 +0,0 @@
-// Copyright (c) 2012 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.
-
-// This interface is for managing the global services of the application. Each
-// service is lazily created when requested the first time. The service getters
-// will return NULL if the service is not available, so callers must check for
-// this condition.
-
-#ifndef CHROME_BROWSER_BROWSER_PROCESS_H_
-#define CHROME_BROWSER_BROWSER_PROCESS_H_
-
-#include <memory>
-#include <string>
-
-#include "base/macros.h"
-
-namespace printing {
-class PrintJobManager;
-}
-
-// NOT THREAD SAFE, call only from the main thread.
-// These functions shouldn't return NULL unless otherwise noted.
-class BrowserProcess {
- public:
-  BrowserProcess();
-  ~BrowserProcess();
-
-  void SetApplicationLocale(const std::string& locale);
-  std::string GetApplicationLocale();
-
-  printing::PrintJobManager* print_job_manager();
-
- private:
-  std::unique_ptr<printing::PrintJobManager> print_job_manager_;
-  std::string locale_;
-
-  DISALLOW_COPY_AND_ASSIGN(BrowserProcess);
-};
-
-extern BrowserProcess* g_browser_process;
-
-#endif  // CHROME_BROWSER_BROWSER_PROCESS_H_

+ 217 - 0
chromium_src/chrome/browser/browser_process_impl.cc

@@ -0,0 +1,217 @@
+// Copyright (c) 2012 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 "chrome/browser/browser_process_impl.h"
+
+#include "chrome/browser/printing/print_job_manager.h"
+#include "ui/base/l10n/l10n_util.h"
+
+BrowserProcessImpl::BrowserProcessImpl()
+    : print_job_manager_(new printing::PrintJobManager) {
+  g_browser_process = this;
+}
+
+BrowserProcessImpl::~BrowserProcessImpl() {
+  g_browser_process = nullptr;
+}
+
+bool BrowserProcessImpl::IsShuttingDown() {
+  return false;
+}
+
+metrics_services_manager::MetricsServicesManager*
+BrowserProcessImpl::GetMetricsServicesManager() {
+  return nullptr;
+}
+
+metrics::MetricsService* BrowserProcessImpl::metrics_service() {
+  return nullptr;
+}
+
+rappor::RapporServiceImpl* BrowserProcessImpl::rappor_service() {
+  return nullptr;
+}
+
+ProfileManager* BrowserProcessImpl::profile_manager() {
+  return nullptr;
+}
+
+PrefService* BrowserProcessImpl::local_state() {
+  return nullptr;
+}
+
+net::URLRequestContextGetter* BrowserProcessImpl::system_request_context() {
+  return nullptr;
+}
+
+scoped_refptr<network::SharedURLLoaderFactory>
+BrowserProcessImpl::shared_url_loader_factory() {
+  return nullptr;
+}
+
+variations::VariationsService* BrowserProcessImpl::variations_service() {
+  return nullptr;
+}
+
+BrowserProcessPlatformPart* BrowserProcessImpl::platform_part() {
+  return nullptr;
+}
+
+extensions::EventRouterForwarder*
+BrowserProcessImpl::extension_event_router_forwarder() {
+  return nullptr;
+}
+
+NotificationUIManager* BrowserProcessImpl::notification_ui_manager() {
+  return nullptr;
+}
+
+NotificationPlatformBridge* BrowserProcessImpl::notification_platform_bridge() {
+  return nullptr;
+}
+
+IOThread* BrowserProcessImpl::io_thread() {
+  return nullptr;
+}
+
+SystemNetworkContextManager*
+BrowserProcessImpl::system_network_context_manager() {
+  return nullptr;
+}
+
+network::NetworkQualityTracker* BrowserProcessImpl::network_quality_tracker() {
+  return nullptr;
+}
+
+WatchDogThread* BrowserProcessImpl::watchdog_thread() {
+  return nullptr;
+}
+
+policy::ChromeBrowserPolicyConnector*
+BrowserProcessImpl::browser_policy_connector() {
+  return nullptr;
+}
+
+policy::PolicyService* BrowserProcessImpl::policy_service() {
+  return nullptr;
+}
+
+IconManager* BrowserProcessImpl::icon_manager() {
+  return nullptr;
+}
+
+GpuModeManager* BrowserProcessImpl::gpu_mode_manager() {
+  return nullptr;
+}
+
+printing::PrintPreviewDialogController*
+BrowserProcessImpl::print_preview_dialog_controller() {
+  return nullptr;
+}
+
+printing::BackgroundPrintingManager*
+BrowserProcessImpl::background_printing_manager() {
+  return nullptr;
+}
+
+IntranetRedirectDetector* BrowserProcessImpl::intranet_redirect_detector() {
+  return nullptr;
+}
+
+DownloadStatusUpdater* BrowserProcessImpl::download_status_updater() {
+  return nullptr;
+}
+
+DownloadRequestLimiter* BrowserProcessImpl::download_request_limiter() {
+  return nullptr;
+}
+
+BackgroundModeManager* BrowserProcessImpl::background_mode_manager() {
+  return nullptr;
+}
+
+StatusTray* BrowserProcessImpl::status_tray() {
+  return nullptr;
+}
+
+safe_browsing::SafeBrowsingService*
+BrowserProcessImpl::safe_browsing_service() {
+  return nullptr;
+}
+
+safe_browsing::ClientSideDetectionService*
+BrowserProcessImpl::safe_browsing_detection_service() {
+  return nullptr;
+}
+
+subresource_filter::ContentRulesetService*
+BrowserProcessImpl::subresource_filter_ruleset_service() {
+  return nullptr;
+}
+
+optimization_guide::OptimizationGuideService*
+BrowserProcessImpl::optimization_guide_service() {
+  return nullptr;
+}
+
+net_log::ChromeNetLog* BrowserProcessImpl::net_log() {
+  return nullptr;
+}
+
+component_updater::ComponentUpdateService*
+BrowserProcessImpl::component_updater() {
+  return nullptr;
+}
+
+component_updater::SupervisedUserWhitelistInstaller*
+BrowserProcessImpl::supervised_user_whitelist_installer() {
+  return nullptr;
+}
+
+MediaFileSystemRegistry* BrowserProcessImpl::media_file_system_registry() {
+  return nullptr;
+}
+
+WebRtcLogUploader* BrowserProcessImpl::webrtc_log_uploader() {
+  return nullptr;
+}
+
+network_time::NetworkTimeTracker* BrowserProcessImpl::network_time_tracker() {
+  return nullptr;
+}
+
+gcm::GCMDriver* BrowserProcessImpl::gcm_driver() {
+  return nullptr;
+}
+
+resource_coordinator::TabManager* BrowserProcessImpl::GetTabManager() {
+  return nullptr;
+}
+
+shell_integration::DefaultWebClientState
+BrowserProcessImpl::CachedDefaultWebClientState() {
+  return shell_integration::UNKNOWN_DEFAULT;
+}
+
+prefs::InProcessPrefServiceFactory* BrowserProcessImpl::pref_service_factory()
+    const {
+  return nullptr;
+}
+
+content::NetworkConnectionTracker*
+BrowserProcessImpl::network_connection_tracker() {
+  return nullptr;
+}
+
+void BrowserProcessImpl::SetApplicationLocale(const std::string& locale) {
+  locale_ = locale;
+}
+
+const std::string& BrowserProcessImpl::GetApplicationLocale() {
+  return locale_;
+}
+
+printing::PrintJobManager* BrowserProcessImpl::print_job_manager() {
+  return print_job_manager_.get();
+}

+ 107 - 0
chromium_src/chrome/browser/browser_process_impl.h

@@ -0,0 +1,107 @@
+// Copyright (c) 2012 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.
+
+// This interface is for managing the global services of the application. Each
+// service is lazily created when requested the first time. The service getters
+// will return NULL if the service is not available, so callers must check for
+// this condition.
+
+#ifndef CHROME_BROWSER_BROWSER_PROCESS_IMPL_H_
+#define CHROME_BROWSER_BROWSER_PROCESS_IMPL_H_
+
+#include <memory>
+#include <string>
+
+#include "base/macros.h"
+#include "chrome/browser/browser_process.h"
+#include "services/network/public/cpp/shared_url_loader_factory.h"
+
+namespace printing {
+class PrintJobManager;
+}
+
+// Empty definition for std::unique_ptr
+class BackgroundModeManager {};
+
+// NOT THREAD SAFE, call only from the main thread.
+// These functions shouldn't return NULL unless otherwise noted.
+class BrowserProcessImpl : public BrowserProcess {
+ public:
+  BrowserProcessImpl();
+  ~BrowserProcessImpl() override;
+
+  void ResourceDispatcherHostCreated() override {}
+  void EndSession() override {}
+  void FlushLocalStateAndReply(base::OnceClosure reply) override {}
+  bool IsShuttingDown() override;
+
+  metrics_services_manager::MetricsServicesManager* GetMetricsServicesManager()
+      override;
+  metrics::MetricsService* metrics_service() override;
+  rappor::RapporServiceImpl* rappor_service() override;
+  ProfileManager* profile_manager() override;
+  PrefService* local_state() override;
+  net::URLRequestContextGetter* system_request_context() override;
+  scoped_refptr<network::SharedURLLoaderFactory> shared_url_loader_factory()
+      override;
+  variations::VariationsService* variations_service() override;
+  BrowserProcessPlatformPart* platform_part() override;
+  extensions::EventRouterForwarder* extension_event_router_forwarder() override;
+  NotificationUIManager* notification_ui_manager() override;
+  NotificationPlatformBridge* notification_platform_bridge() override;
+  IOThread* io_thread() override;
+  SystemNetworkContextManager* system_network_context_manager() override;
+  network::NetworkQualityTracker* network_quality_tracker() override;
+  WatchDogThread* watchdog_thread() override;
+  policy::ChromeBrowserPolicyConnector* browser_policy_connector() override;
+  policy::PolicyService* policy_service() override;
+  IconManager* icon_manager() override;
+  GpuModeManager* gpu_mode_manager() override;
+  printing::PrintPreviewDialogController* print_preview_dialog_controller()
+      override;
+  printing::BackgroundPrintingManager* background_printing_manager() override;
+  IntranetRedirectDetector* intranet_redirect_detector() override;
+  DownloadStatusUpdater* download_status_updater() override;
+  DownloadRequestLimiter* download_request_limiter() override;
+  BackgroundModeManager* background_mode_manager() override;
+  StatusTray* status_tray() override;
+  safe_browsing::SafeBrowsingService* safe_browsing_service() override;
+  safe_browsing::ClientSideDetectionService* safe_browsing_detection_service()
+      override;
+  subresource_filter::ContentRulesetService*
+  subresource_filter_ruleset_service() override;
+  optimization_guide::OptimizationGuideService* optimization_guide_service()
+      override;
+  net_log::ChromeNetLog* net_log() override;
+  component_updater::ComponentUpdateService* component_updater() override;
+  component_updater::SupervisedUserWhitelistInstaller*
+  supervised_user_whitelist_installer() override;
+  MediaFileSystemRegistry* media_file_system_registry() override;
+  WebRtcLogUploader* webrtc_log_uploader() override;
+  network_time::NetworkTimeTracker* network_time_tracker() override;
+  gcm::GCMDriver* gcm_driver() override;
+  resource_coordinator::TabManager* GetTabManager() override;
+  shell_integration::DefaultWebClientState CachedDefaultWebClientState()
+      override;
+  prefs::InProcessPrefServiceFactory* pref_service_factory() const override;
+  content::NetworkConnectionTracker* network_connection_tracker() override;
+  void CreateDevToolsProtocolHandler() override {}
+  void CreateDevToolsAutoOpener() override {}
+  void set_background_mode_manager_for_test(
+      std::unique_ptr<BackgroundModeManager> manager) override {}
+#if (defined(OS_WIN) || defined(OS_LINUX))
+  void StartAutoupdateTimer() override {}
+#endif
+  void SetApplicationLocale(const std::string& locale) override;
+  const std::string& GetApplicationLocale() override;
+  printing::PrintJobManager* print_job_manager() override;
+
+ private:
+  std::unique_ptr<printing::PrintJobManager> print_job_manager_;
+  std::string locale_;
+
+  DISALLOW_COPY_AND_ASSIGN(BrowserProcessImpl);
+};
+
+#endif  // CHROME_BROWSER_BROWSER_PROCESS_IMPL_H_

+ 0 - 336
chromium_src/chrome/browser/speech/tts_controller.h

@@ -1,336 +0,0 @@
-// Copyright (c) 2012 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 CHROME_BROWSER_SPEECH_TTS_CONTROLLER_H_
-#define CHROME_BROWSER_SPEECH_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 content {
-class BrowserContext;
-}
-
-// 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&);
-  ~VoiceData();
-
-  std::string name;
-  std::string lang;
-  TtsGenderType gender;
-  std::string extension_id;
-  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;
-};
-
-// Interface that delegates TTS requests to user-installed extensions.
-class TtsEngineDelegate {
- public:
-  virtual ~TtsEngineDelegate() {}
-
-  // Return a list of all available voices registered.
-  virtual void GetVoices(content::BrowserContext* browser_context,
-                         std::vector<VoiceData>* out_voices) = 0;
-
-  // Speak the given utterance by sending an event to the given TTS engine.
-  virtual void Speak(Utterance* utterance, const VoiceData& voice) = 0;
-
-  // Stop speaking the given utterance by sending an event to the target
-  // associated with this utterance.
-  virtual void Stop(Utterance* utterance) = 0;
-
-  // Pause in the middle of speaking this utterance.
-  virtual void Pause(Utterance* utterance) = 0;
-
-  // Resume speaking this utterance.
-  virtual void Resume(Utterance* utterance) = 0;
-
-  // Load the built-in component extension for ChromeOS.
-  virtual bool LoadBuiltInTtsExtension(
-      content::BrowserContext* browser_context) = 0;
-};
-
-// 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;
-};
-
-// Class that wants to be notified when the set of
-// voices has changed.
-class VoicesChangedDelegate {
- public:
-  virtual ~VoicesChangedDelegate() {}
-  virtual void OnVoicesChanged() = 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_extension_id(const std::string& src_extension_id) {
-    src_extension_id_ = src_extension_id;
-  }
-  const std::string& src_extension_id() { return src_extension_id_; }
-
-  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 UtteranceContinuousParameters& params) {
-    continuous_parameters_ = params;
-  }
-  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_.get();
-  }
-  void set_event_delegate(
-      base::WeakPtr<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 extension ID of the extension that called speak() and should
-  // receive events.
-  std::string src_extension_id_;
-
-  // 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.
-  base::WeakPtr<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 and TTS engine
-// extension APIs, maintaining a queue of pending utterances and keeping
-// track of all state.
-class TtsController {
- public:
-  // Get the single instance of this class.
-  static TtsController* GetInstance();
-
-  // 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;
-
-  // Called by the extension system or platform implementation when the
-  // list of voices may have changed and should be re-queried.
-  virtual void VoicesChanged() = 0;
-
-  // Add a delegate that wants to be notified when the set of voices changes.
-  virtual void AddVoicesChangedDelegate(VoicesChangedDelegate* delegate) = 0;
-
-  // Remove delegate that wants to be notified when the set of voices changes.
-  virtual void RemoveVoicesChangedDelegate(VoicesChangedDelegate* delegate) = 0;
-
-  // Set the delegate that processes TTS requests with user-installed
-  // extensions.
-  virtual void SetTtsEngineDelegate(TtsEngineDelegate* delegate) = 0;
-
-  // Get the delegate that processes TTS requests with user-installed
-  // extensions.
-  virtual TtsEngineDelegate* GetTtsEngineDelegate() = 0;
-
-  // For unit testing.
-  virtual void SetPlatformImpl(TtsPlatformImpl* platform_impl) = 0;
-  virtual int QueueSize() = 0;
-
- protected:
-  virtual ~TtsController() {}
-};
-
-#endif  // CHROME_BROWSER_SPEECH_TTS_CONTROLLER_H_

+ 0 - 447
chromium_src/chrome/browser/speech/tts_controller_impl.cc

@@ -1,447 +0,0 @@
-// Copyright 2014 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 "chrome/browser/speech/tts_controller_impl.h"
-
-#include <string>
-#include <vector>
-
-#include "base/values.h"
-#include "chrome/browser/browser_process.h"
-#include "chrome/browser/speech/tts_platform.h"
-
-namespace {
-// A value to be used to indicate that there is no char index available.
-const int kInvalidCharIndex = -1;
-
-// Given a language/region code of the form 'fr-FR', returns just the basic
-// language portion, e.g. 'fr'.
-std::string TrimLanguageCode(std::string lang) {
-  if (lang.size() >= 5 && lang[2] == '-')
-    return lang.substr(0, 2);
-  else
-    return lang;
-}
-
-}  // namespace
-
-bool IsFinalTtsEventType(TtsEventType event_type) {
-  return (event_type == TTS_EVENT_END || event_type == TTS_EVENT_INTERRUPTED ||
-          event_type == TTS_EVENT_CANCELLED || event_type == TTS_EVENT_ERROR);
-}
-
-//
-// UtteranceContinuousParameters
-//
-
-UtteranceContinuousParameters::UtteranceContinuousParameters()
-    : rate(-1), pitch(-1), volume(-1) {}
-
-//
-// VoiceData
-//
-
-VoiceData::VoiceData()
-    : gender(TTS_GENDER_NONE), remote(false), native(false) {}
-
-VoiceData::VoiceData(const VoiceData&) = default;
-
-VoiceData::~VoiceData() = default;
-
-//
-// Utterance
-//
-
-// static
-int Utterance::next_utterance_id_ = 0;
-
-Utterance::Utterance(content::BrowserContext* browser_context)
-    : browser_context_(browser_context),
-      id_(next_utterance_id_++),
-      src_id_(-1),
-      gender_(TTS_GENDER_NONE),
-      can_enqueue_(false),
-      char_index_(0),
-      finished_(false) {
-  options_.reset(new base::DictionaryValue());
-}
-
-Utterance::~Utterance() {
-  DCHECK(finished_);
-}
-
-void Utterance::OnTtsEvent(TtsEventType event_type,
-                           int char_index,
-                           const std::string& error_message) {
-  if (char_index >= 0)
-    char_index_ = char_index;
-  if (IsFinalTtsEventType(event_type))
-    finished_ = true;
-
-  if (event_delegate_)
-    event_delegate_->OnTtsEvent(this, event_type, char_index, error_message);
-  if (finished_)
-    event_delegate_.reset();
-}
-
-void Utterance::Finish() {
-  finished_ = true;
-}
-
-void Utterance::set_options(const base::Value* options) {
-  options_.reset(options->DeepCopy());
-}
-
-TtsController* TtsController::GetInstance() {
-  return TtsControllerImpl::GetInstance();
-}
-
-//
-// TtsControllerImpl
-//
-
-// static
-TtsControllerImpl* TtsControllerImpl::GetInstance() {
-  return base::Singleton<TtsControllerImpl>::get();
-}
-
-TtsControllerImpl::TtsControllerImpl()
-    : current_utterance_(NULL),
-      paused_(false),
-      platform_impl_(NULL),
-      tts_engine_delegate_(NULL) {}
-
-TtsControllerImpl::~TtsControllerImpl() {
-  if (current_utterance_) {
-    current_utterance_->Finish();
-    delete current_utterance_;
-  }
-
-  // Clear any queued utterances too.
-  ClearUtteranceQueue(false);  // Don't sent events.
-}
-
-void TtsControllerImpl::SpeakOrEnqueue(Utterance* utterance) {
-  // 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->can_enqueue()) {
-    Stop();
-    paused_ = true;
-    delete utterance;
-    return;
-  }
-
-  if (paused_ || (IsSpeaking() && utterance->can_enqueue())) {
-    utterance_queue_.push(utterance);
-  } else {
-    Stop();
-    SpeakNow(utterance);
-  }
-}
-
-void TtsControllerImpl::SpeakNow(Utterance* utterance) {
-  // Ensure we have all built-in voices loaded. This is a no-op if already
-  // loaded.
-  bool loaded_built_in =
-      GetPlatformImpl()->LoadBuiltInTtsExtension(utterance->browser_context());
-
-  // Get all available voices and try to find a matching voice.
-  std::vector<VoiceData> voices;
-  GetVoices(utterance->browser_context(), &voices);
-  int index = GetMatchingVoice(utterance, voices);
-
-  VoiceData voice;
-  if (index != -1) {
-    // Select the matching voice.
-    voice = voices[index];
-  } else {
-    // However, if no match was found on a platform without native tts voices,
-    // attempt to get a voice based only on the current locale without respect
-    // to any supplied voice names.
-    std::vector<VoiceData> native_voices;
-
-    if (GetPlatformImpl()->PlatformImplAvailable())
-      GetPlatformImpl()->GetVoices(&native_voices);
-
-    if (native_voices.empty() && !voices.empty()) {
-      // TODO(dtseng): Notify extension caller of an error.
-      utterance->set_voice_name("");
-      // TODO(gaochun): Replace the global variable g_browser_process with
-      // GetContentClient()->browser() to eliminate the dependency of browser
-      // once TTS implementation was moved to content.
-      utterance->set_lang(g_browser_process->GetApplicationLocale());
-      index = GetMatchingVoice(utterance, voices);
-
-      // If even that fails, just take the first available voice.
-      if (index == -1)
-        index = 0;
-      voice = voices[index];
-    } else {
-      // Otherwise, simply give native voices a chance to handle this utterance.
-      voice.native = true;
-    }
-  }
-
-  GetPlatformImpl()->WillSpeakUtteranceWithVoice(utterance, voice);
-
-  if (!voice.native) {
-#if !defined(OS_ANDROID)
-    DCHECK(!voice.extension_id.empty());
-    current_utterance_ = utterance;
-    utterance->set_extension_id(voice.extension_id);
-    if (tts_engine_delegate_)
-      tts_engine_delegate_->Speak(utterance, voice);
-    bool sends_end_event =
-        voice.events.find(TTS_EVENT_END) != voice.events.end();
-    if (!sends_end_event) {
-      utterance->Finish();
-      delete utterance;
-      current_utterance_ = NULL;
-      SpeakNextUtterance();
-    }
-#endif
-  } else {
-    // It's possible for certain platforms to send start events immediately
-    // during |speak|.
-    current_utterance_ = utterance;
-    GetPlatformImpl()->clear_error();
-    bool success = GetPlatformImpl()->Speak(utterance->id(), utterance->text(),
-                                            utterance->lang(), voice,
-                                            utterance->continuous_parameters());
-    if (!success)
-      current_utterance_ = NULL;
-
-    // If the native voice wasn't able to process this speech, see if
-    // the browser has built-in TTS that isn't loaded yet.
-    if (!success && loaded_built_in) {
-      utterance_queue_.push(utterance);
-      return;
-    }
-
-    if (!success) {
-      utterance->OnTtsEvent(TTS_EVENT_ERROR, kInvalidCharIndex,
-                            GetPlatformImpl()->error());
-      delete utterance;
-      return;
-    }
-  }
-}
-
-void TtsControllerImpl::Stop() {
-  paused_ = false;
-  if (current_utterance_ && !current_utterance_->extension_id().empty()) {
-#if !defined(OS_ANDROID)
-    if (tts_engine_delegate_)
-      tts_engine_delegate_->Stop(current_utterance_);
-#endif
-  } else {
-    GetPlatformImpl()->clear_error();
-    GetPlatformImpl()->StopSpeaking();
-  }
-
-  if (current_utterance_)
-    current_utterance_->OnTtsEvent(TTS_EVENT_INTERRUPTED, kInvalidCharIndex,
-                                   std::string());
-  FinishCurrentUtterance();
-  ClearUtteranceQueue(true);  // Send events.
-}
-
-void TtsControllerImpl::Pause() {
-  paused_ = true;
-  if (current_utterance_ && !current_utterance_->extension_id().empty()) {
-#if !defined(OS_ANDROID)
-    if (tts_engine_delegate_)
-      tts_engine_delegate_->Pause(current_utterance_);
-#endif
-  } else if (current_utterance_) {
-    GetPlatformImpl()->clear_error();
-    GetPlatformImpl()->Pause();
-  }
-}
-
-void TtsControllerImpl::Resume() {
-  paused_ = false;
-  if (current_utterance_ && !current_utterance_->extension_id().empty()) {
-#if !defined(OS_ANDROID)
-    if (tts_engine_delegate_)
-      tts_engine_delegate_->Resume(current_utterance_);
-#endif
-  } else if (current_utterance_) {
-    GetPlatformImpl()->clear_error();
-    GetPlatformImpl()->Resume();
-  } else {
-    SpeakNextUtterance();
-  }
-}
-
-void TtsControllerImpl::OnTtsEvent(int utterance_id,
-                                   TtsEventType event_type,
-                                   int char_index,
-                                   const std::string& error_message) {
-  // We may sometimes receive completion callbacks "late", after we've
-  // already finished the utterance (for example because another utterance
-  // interrupted or we got a call to Stop). This is normal and we can
-  // safely just ignore these events.
-  if (!current_utterance_ || utterance_id != current_utterance_->id()) {
-    return;
-  }
-  current_utterance_->OnTtsEvent(event_type, char_index, error_message);
-  if (current_utterance_->finished()) {
-    FinishCurrentUtterance();
-    SpeakNextUtterance();
-  }
-}
-
-void TtsControllerImpl::GetVoices(content::BrowserContext* browser_context,
-                                  std::vector<VoiceData>* out_voices) {
-#if !defined(OS_ANDROID)
-  if (browser_context && tts_engine_delegate_)
-    tts_engine_delegate_->GetVoices(browser_context, out_voices);
-#endif
-
-  TtsPlatformImpl* platform_impl = GetPlatformImpl();
-  if (platform_impl) {
-    // Ensure we have all built-in voices loaded. This is a no-op if already
-    // loaded.
-    platform_impl->LoadBuiltInTtsExtension(browser_context);
-    if (platform_impl->PlatformImplAvailable())
-      platform_impl->GetVoices(out_voices);
-  }
-}
-
-bool TtsControllerImpl::IsSpeaking() {
-  return current_utterance_ != NULL || GetPlatformImpl()->IsSpeaking();
-}
-
-void TtsControllerImpl::FinishCurrentUtterance() {
-  if (current_utterance_) {
-    if (!current_utterance_->finished())
-      current_utterance_->OnTtsEvent(TTS_EVENT_INTERRUPTED, kInvalidCharIndex,
-                                     std::string());
-    delete current_utterance_;
-    current_utterance_ = NULL;
-  }
-}
-
-void TtsControllerImpl::SpeakNextUtterance() {
-  if (paused_)
-    return;
-
-  // Start speaking the next utterance in the queue.  Keep trying in case
-  // one fails but there are still more in the queue to try.
-  while (!utterance_queue_.empty() && !current_utterance_) {
-    Utterance* utterance = utterance_queue_.front();
-    utterance_queue_.pop();
-    SpeakNow(utterance);
-  }
-}
-
-void TtsControllerImpl::ClearUtteranceQueue(bool send_events) {
-  while (!utterance_queue_.empty()) {
-    Utterance* utterance = utterance_queue_.front();
-    utterance_queue_.pop();
-    if (send_events)
-      utterance->OnTtsEvent(TTS_EVENT_CANCELLED, kInvalidCharIndex,
-                            std::string());
-    else
-      utterance->Finish();
-    delete utterance;
-  }
-}
-
-void TtsControllerImpl::SetPlatformImpl(TtsPlatformImpl* platform_impl) {
-  platform_impl_ = platform_impl;
-}
-
-int TtsControllerImpl::QueueSize() {
-  return static_cast<int>(utterance_queue_.size());
-}
-
-TtsPlatformImpl* TtsControllerImpl::GetPlatformImpl() {
-  if (!platform_impl_)
-    platform_impl_ = TtsPlatformImpl::GetInstance();
-  return platform_impl_;
-}
-
-int TtsControllerImpl::GetMatchingVoice(const Utterance* utterance,
-                                        std::vector<VoiceData>& voices) {
-  // Make two passes: the first time, do strict language matching
-  // ('fr-FR' does not match 'fr-CA'). The second time, do prefix
-  // language matching ('fr-FR' matches 'fr' and 'fr-CA')
-  for (int pass = 0; pass < 2; ++pass) {
-    for (size_t i = 0; i < voices.size(); ++i) {
-      const VoiceData& voice = voices[i];
-
-      if (!utterance->extension_id().empty() &&
-          utterance->extension_id() != voice.extension_id) {
-        continue;
-      }
-
-      if (!voice.name.empty() && !utterance->voice_name().empty() &&
-          voice.name != utterance->voice_name()) {
-        continue;
-      }
-      if (!voice.lang.empty() && !utterance->lang().empty()) {
-        std::string voice_lang = voice.lang;
-        std::string utterance_lang = utterance->lang();
-        if (pass == 1) {
-          voice_lang = TrimLanguageCode(voice_lang);
-          utterance_lang = TrimLanguageCode(utterance_lang);
-        }
-        if (voice_lang != utterance_lang) {
-          continue;
-        }
-      }
-      if (voice.gender != TTS_GENDER_NONE &&
-          utterance->gender() != TTS_GENDER_NONE &&
-          voice.gender != utterance->gender()) {
-        continue;
-      }
-
-      if (utterance->required_event_types().size() > 0) {
-        bool has_all_required_event_types = true;
-        for (std::set<TtsEventType>::const_iterator iter =
-                 utterance->required_event_types().begin();
-             iter != utterance->required_event_types().end(); ++iter) {
-          if (voice.events.find(*iter) == voice.events.end()) {
-            has_all_required_event_types = false;
-            break;
-          }
-        }
-        if (!has_all_required_event_types)
-          continue;
-      }
-
-      return static_cast<int>(i);
-    }
-  }
-
-  return -1;
-}
-
-void TtsControllerImpl::VoicesChanged() {
-  for (std::set<VoicesChangedDelegate*>::iterator iter =
-           voices_changed_delegates_.begin();
-       iter != voices_changed_delegates_.end(); ++iter) {
-    (*iter)->OnVoicesChanged();
-  }
-}
-
-void TtsControllerImpl::AddVoicesChangedDelegate(
-    VoicesChangedDelegate* delegate) {
-  voices_changed_delegates_.insert(delegate);
-}
-
-void TtsControllerImpl::RemoveVoicesChangedDelegate(
-    VoicesChangedDelegate* delegate) {
-  voices_changed_delegates_.erase(delegate);
-}
-
-void TtsControllerImpl::SetTtsEngineDelegate(TtsEngineDelegate* delegate) {
-  tts_engine_delegate_ = delegate;
-}
-
-TtsEngineDelegate* TtsControllerImpl::GetTtsEngineDelegate() {
-  return tts_engine_delegate_;
-}

+ 0 - 102
chromium_src/chrome/browser/speech/tts_controller_impl.h

@@ -1,102 +0,0 @@
-// Copyright 2014 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 CHROME_BROWSER_SPEECH_TTS_CONTROLLER_IMPL_H_
-#define CHROME_BROWSER_SPEECH_TTS_CONTROLLER_IMPL_H_
-
-#include <memory>
-#include <queue>
-#include <set>
-#include <string>
-#include <vector>
-
-#include "base/memory/singleton.h"
-#include "base/memory/weak_ptr.h"
-#include "chrome/browser/speech/tts_controller.h"
-#include "url/gurl.h"
-
-namespace content {
-class BrowserContext;
-}
-
-// 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:
-  // Get the single instance of this class.
-  static TtsControllerImpl* GetInstance();
-
-  // 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 VoicesChanged() override;
-  void AddVoicesChangedDelegate(VoicesChangedDelegate* delegate) override;
-  void RemoveVoicesChangedDelegate(VoicesChangedDelegate* delegate) override;
-  void SetTtsEngineDelegate(TtsEngineDelegate* delegate) override;
-  TtsEngineDelegate* GetTtsEngineDelegate() override;
-  void SetPlatformImpl(TtsPlatformImpl* platform_impl) override;
-  int QueueSize() override;
-
- protected:
-  TtsControllerImpl();
-  ~TtsControllerImpl() override;
-
- private:
-  // 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);
-
-  friend struct base::DefaultSingletonTraits<TtsControllerImpl>;
-
-  // 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.
-  std::queue<Utterance*> utterance_queue_;
-
-  // A set of delegates that want to be notified when the voices change.
-  std::set<VoicesChangedDelegate*> voices_changed_delegates_;
-
-  // A pointer to the platform implementation of text-to-speech, for
-  // dependency injection.
-  TtsPlatformImpl* platform_impl_;
-
-  // The delegate that processes TTS requests with user-installed extensions.
-  TtsEngineDelegate* tts_engine_delegate_;
-
-  DISALLOW_COPY_AND_ASSIGN(TtsControllerImpl);
-};
-
-#endif  // CHROME_BROWSER_SPEECH_TTS_CONTROLLER_IMPL_H_

+ 0 - 349
chromium_src/chrome/browser/speech/tts_linux.cc

@@ -1,349 +0,0 @@
-// Copyright (c) 2012 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 <math.h>
-
-#include <map>
-#include <memory>
-
-#include "base/command_line.h"
-#include "base/debug/leak_annotations.h"
-#include "base/memory/singleton.h"
-#include "base/synchronization/lock.h"
-#include "base/task_scheduler/post_task.h"
-#include "chrome/browser/speech/tts_platform.h"
-#include "content/public/browser/browser_thread.h"
-#include "content/public/common/content_switches.h"
-
-#include "library_loaders/libspeechd.h"
-
-using content::BrowserThread;
-
-namespace {
-
-const char kNotSupportedError[] =
-    "Native speech synthesis not supported on this platform.";
-
-struct SPDChromeVoice {
-  std::string name;
-  std::string module;
-};
-
-}  // namespace
-
-class TtsPlatformImplLinux : public TtsPlatformImpl {
- public:
-  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;
-
-  void OnSpeechEvent(SPDNotificationType type);
-
-  // Get the single instance of this class.
-  static TtsPlatformImplLinux* GetInstance();
-
- private:
-  TtsPlatformImplLinux();
-  ~TtsPlatformImplLinux() override;
-
-  // Initiate the connection with the speech dispatcher.
-  void Initialize();
-
-  // Resets the connection with speech dispatcher.
-  void Reset();
-
-  static void NotificationCallback(size_t msg_id,
-                                   size_t client_id,
-                                   SPDNotificationType type);
-
-  static void IndexMarkCallback(size_t msg_id,
-                                size_t client_id,
-                                SPDNotificationType state,
-                                char* index_mark);
-
-  static SPDNotificationType current_notification_;
-
-  base::Lock initialization_lock_;
-  LibSpeechdLoader libspeechd_loader_;
-  SPDConnection* conn_;
-
-  // These apply to the current utterance only.
-  std::string utterance_;
-  int utterance_id_;
-
-  // Map a string composed of a voicename and module to the voicename. Used to
-  // uniquely identify a voice across all available modules.
-  std::unique_ptr<std::map<std::string, SPDChromeVoice>> all_native_voices_;
-
-  friend struct base::DefaultSingletonTraits<TtsPlatformImplLinux>;
-
-  DISALLOW_COPY_AND_ASSIGN(TtsPlatformImplLinux);
-};
-
-// static
-SPDNotificationType TtsPlatformImplLinux::current_notification_ = SPD_EVENT_END;
-
-TtsPlatformImplLinux::TtsPlatformImplLinux() : utterance_id_(0) {
-  const base::CommandLine& command_line =
-      *base::CommandLine::ForCurrentProcess();
-  if (!command_line.HasSwitch(switches::kEnableSpeechDispatcher))
-    return;
-
-  base::PostTaskWithTraits(
-      FROM_HERE, {base::MayBlock(), base::TaskPriority::BACKGROUND},
-      base::Bind(&TtsPlatformImplLinux::Initialize, base::Unretained(this)));
-}
-
-void TtsPlatformImplLinux::Initialize() {
-  base::AutoLock lock(initialization_lock_);
-
-  if (!libspeechd_loader_.Load("libspeechd.so.2"))
-    return;
-
-  {
-    // spd_open has memory leaks which are hard to suppress.
-    // http://crbug.com/317360
-    ANNOTATE_SCOPED_MEMORY_LEAK;
-    conn_ = libspeechd_loader_.spd_open("chrome", "extension_api", NULL,
-                                        SPD_MODE_THREADED);
-  }
-  if (!conn_)
-    return;
-
-  // Register callbacks for all events.
-  conn_->callback_begin = conn_->callback_end = conn_->callback_cancel =
-      conn_->callback_pause = conn_->callback_resume = &NotificationCallback;
-
-  conn_->callback_im = &IndexMarkCallback;
-
-  libspeechd_loader_.spd_set_notification_on(conn_, SPD_BEGIN);
-  libspeechd_loader_.spd_set_notification_on(conn_, SPD_END);
-  libspeechd_loader_.spd_set_notification_on(conn_, SPD_CANCEL);
-  libspeechd_loader_.spd_set_notification_on(conn_, SPD_PAUSE);
-  libspeechd_loader_.spd_set_notification_on(conn_, SPD_RESUME);
-}
-
-TtsPlatformImplLinux::~TtsPlatformImplLinux() {
-  base::AutoLock lock(initialization_lock_);
-  if (conn_) {
-    libspeechd_loader_.spd_close(conn_);
-    conn_ = NULL;
-  }
-}
-
-void TtsPlatformImplLinux::Reset() {
-  base::AutoLock lock(initialization_lock_);
-  if (conn_)
-    libspeechd_loader_.spd_close(conn_);
-  conn_ = libspeechd_loader_.spd_open("chrome", "extension_api", NULL,
-                                      SPD_MODE_THREADED);
-}
-
-bool TtsPlatformImplLinux::PlatformImplAvailable() {
-  if (!initialization_lock_.Try())
-    return false;
-  bool result = libspeechd_loader_.loaded() && (conn_ != NULL);
-  initialization_lock_.Release();
-  return result;
-}
-
-bool TtsPlatformImplLinux::Speak(int utterance_id,
-                                 const std::string& utterance,
-                                 const std::string& lang,
-                                 const VoiceData& voice,
-                                 const UtteranceContinuousParameters& params) {
-  if (!PlatformImplAvailable()) {
-    error_ = kNotSupportedError;
-    return false;
-  }
-
-  // Speech dispatcher's speech params are around 3x at either limit.
-  float rate = params.rate > 3 ? 3 : params.rate;
-  rate = params.rate < 0.334 ? 0.334 : rate;
-  float pitch = params.pitch > 3 ? 3 : params.pitch;
-  pitch = params.pitch < 0.334 ? 0.334 : pitch;
-
-  std::map<std::string, SPDChromeVoice>::iterator it =
-      all_native_voices_->find(voice.name);
-  if (it != all_native_voices_->end()) {
-    libspeechd_loader_.spd_set_output_module(conn_, it->second.module.c_str());
-    libspeechd_loader_.spd_set_synthesis_voice(conn_, it->second.name.c_str());
-  }
-
-  // Map our multiplicative range to Speech Dispatcher's linear range.
-  // .334 = -100.
-  // 3 = 100.
-  libspeechd_loader_.spd_set_voice_rate(conn_, 100 * log10(rate) / log10(3));
-  libspeechd_loader_.spd_set_voice_pitch(conn_, 100 * log10(pitch) / log10(3));
-
-  // Support languages other than the default
-  if (!lang.empty())
-    libspeechd_loader_.spd_set_language(conn_, lang.c_str());
-
-  utterance_ = utterance;
-  utterance_id_ = utterance_id;
-
-  if (libspeechd_loader_.spd_say(conn_, SPD_TEXT, utterance.c_str()) == -1) {
-    Reset();
-    return false;
-  }
-  return true;
-}
-
-bool TtsPlatformImplLinux::StopSpeaking() {
-  if (!PlatformImplAvailable())
-    return false;
-  if (libspeechd_loader_.spd_stop(conn_) == -1) {
-    Reset();
-    return false;
-  }
-  return true;
-}
-
-void TtsPlatformImplLinux::Pause() {
-  if (!PlatformImplAvailable())
-    return;
-  libspeechd_loader_.spd_pause(conn_);
-}
-
-void TtsPlatformImplLinux::Resume() {
-  if (!PlatformImplAvailable())
-    return;
-  libspeechd_loader_.spd_resume(conn_);
-}
-
-bool TtsPlatformImplLinux::IsSpeaking() {
-  return current_notification_ == SPD_EVENT_BEGIN;
-}
-
-void TtsPlatformImplLinux::GetVoices(std::vector<VoiceData>* out_voices) {
-  if (!all_native_voices_.get()) {
-    all_native_voices_.reset(new std::map<std::string, SPDChromeVoice>());
-    char** modules = libspeechd_loader_.spd_list_modules(conn_);
-    if (!modules)
-      return;
-    for (int i = 0; modules[i]; i++) {
-      char* module = modules[i];
-      libspeechd_loader_.spd_set_output_module(conn_, module);
-      SPDVoice** native_voices =
-          libspeechd_loader_.spd_list_synthesis_voices(conn_);
-      if (!native_voices) {
-        free(module);
-        continue;
-      }
-      for (int j = 0; native_voices[j]; j++) {
-        SPDVoice* native_voice = native_voices[j];
-        SPDChromeVoice native_data;
-        native_data.name = native_voice->name;
-        native_data.module = module;
-        std::string key;
-        key.append(native_data.name);
-        key.append(" ");
-        key.append(native_data.module);
-        all_native_voices_->insert(
-            std::pair<std::string, SPDChromeVoice>(key, native_data));
-        free(native_voices[j]);
-      }
-      free(modules[i]);
-    }
-  }
-
-  for (std::map<std::string, SPDChromeVoice>::iterator it =
-           all_native_voices_->begin();
-       it != all_native_voices_->end(); it++) {
-    out_voices->push_back(VoiceData());
-    VoiceData& voice = out_voices->back();
-    voice.native = true;
-    voice.name = it->first;
-    voice.events.insert(TTS_EVENT_START);
-    voice.events.insert(TTS_EVENT_END);
-    voice.events.insert(TTS_EVENT_CANCELLED);
-    voice.events.insert(TTS_EVENT_MARKER);
-    voice.events.insert(TTS_EVENT_PAUSE);
-    voice.events.insert(TTS_EVENT_RESUME);
-  }
-}
-
-void TtsPlatformImplLinux::OnSpeechEvent(SPDNotificationType type) {
-  TtsController* controller = TtsController::GetInstance();
-  switch (type) {
-    case SPD_EVENT_BEGIN:
-      controller->OnTtsEvent(utterance_id_, TTS_EVENT_START, 0, std::string());
-      break;
-    case SPD_EVENT_RESUME:
-      controller->OnTtsEvent(utterance_id_, TTS_EVENT_RESUME, 0, std::string());
-      break;
-    case SPD_EVENT_END:
-      controller->OnTtsEvent(utterance_id_, TTS_EVENT_END, utterance_.size(),
-                             std::string());
-      break;
-    case SPD_EVENT_PAUSE:
-      controller->OnTtsEvent(utterance_id_, TTS_EVENT_PAUSE, utterance_.size(),
-                             std::string());
-      break;
-    case SPD_EVENT_CANCEL:
-      controller->OnTtsEvent(utterance_id_, TTS_EVENT_CANCELLED, 0,
-                             std::string());
-      break;
-    case SPD_EVENT_INDEX_MARK:
-      controller->OnTtsEvent(utterance_id_, TTS_EVENT_MARKER, 0, std::string());
-      break;
-  }
-}
-
-// static
-void TtsPlatformImplLinux::NotificationCallback(size_t msg_id,
-                                                size_t client_id,
-                                                SPDNotificationType type) {
-  // We run Speech Dispatcher in threaded mode, so these callbacks should always
-  // be in a separate thread.
-  if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
-    current_notification_ = type;
-    BrowserThread::PostTask(
-        BrowserThread::UI, FROM_HERE,
-        base::Bind(&TtsPlatformImplLinux::OnSpeechEvent,
-                   base::Unretained(TtsPlatformImplLinux::GetInstance()),
-                   type));
-  }
-}
-
-// static
-void TtsPlatformImplLinux::IndexMarkCallback(size_t msg_id,
-                                             size_t client_id,
-                                             SPDNotificationType state,
-                                             char* index_mark) {
-  // TODO(dtseng): index_mark appears to specify an index type supplied by a
-  // client. Need to explore how this is used before hooking it up with existing
-  // word, sentence events.
-  // We run Speech Dispatcher in threaded mode, so these callbacks should always
-  // be in a separate thread.
-  if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
-    current_notification_ = state;
-    BrowserThread::PostTask(
-        BrowserThread::UI, FROM_HERE,
-        base::Bind(&TtsPlatformImplLinux::OnSpeechEvent,
-                   base::Unretained(TtsPlatformImplLinux::GetInstance()),
-                   state));
-  }
-}
-
-// static
-TtsPlatformImplLinux* TtsPlatformImplLinux::GetInstance() {
-  return base::Singleton<
-      TtsPlatformImplLinux,
-      base::LeakySingletonTraits<TtsPlatformImplLinux>>::get();
-}
-
-// static
-TtsPlatformImpl* TtsPlatformImpl::GetInstance() {
-  return TtsPlatformImplLinux::GetInstance();
-}

+ 0 - 344
chromium_src/chrome/browser/speech/tts_mac.mm

@@ -1,344 +0,0 @@
-// Copyright (c) 2012 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 <string>
-
-#include "base/mac/scoped_nsobject.h"
-#include "base/memory/singleton.h"
-#include "base/strings/sys_string_conversions.h"
-#include "base/values.h"
-#include "chrome/browser/speech/tts_controller.h"
-#include "chrome/browser/speech/tts_platform.h"
-
-#import <Cocoa/Cocoa.h>
-
-class TtsPlatformImplMac;
-
-@interface ChromeTtsDelegate : NSObject <NSSpeechSynthesizerDelegate> {
- @private
-  TtsPlatformImplMac* ttsImplMac_;  // weak.
-}
-
-- (id)initWithPlatformImplMac:(TtsPlatformImplMac*)ttsImplMac;
-
-@end
-
-// Subclass of NSSpeechSynthesizer that takes an utterance
-// string on initialization, retains it and only allows it
-// to be spoken once.
-//
-// We construct a new NSSpeechSynthesizer for each utterance, for
-// two reasons:
-// 1. To associate delegate callbacks with a particular utterance,
-//    without assuming anything undocumented about the protocol.
-// 2. To work around http://openradar.appspot.com/radar?id=2854403,
-//    where Nuance voices don't retain the utterance string and
-//    crash when trying to call willSpeakWord.
-@interface SingleUseSpeechSynthesizer : NSSpeechSynthesizer {
- @private
-  base::scoped_nsobject<NSString> utterance_;
-  bool didSpeak_;
-}
-
-- (id)initWithUtterance:(NSString*)utterance;
-- (bool)startSpeakingRetainedUtterance;
-- (bool)startSpeakingString:(NSString*)utterance;
-
-@end
-
-class TtsPlatformImplMac : public TtsPlatformImpl {
- public:
-  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;
-
-  bool StopSpeaking() override;
-
-  void Pause() override;
-
-  void Resume() override;
-
-  bool IsSpeaking() override;
-
-  void GetVoices(std::vector<VoiceData>* out_voices) override;
-
-  // Called by ChromeTtsDelegate when we get a callback from the
-  // native speech engine.
-  void OnSpeechEvent(NSSpeechSynthesizer* sender,
-                     TtsEventType event_type,
-                     int char_index,
-                     const std::string& error_message);
-
-  // Get the single instance of this class.
-  static TtsPlatformImplMac* GetInstance();
-
- private:
-  TtsPlatformImplMac();
-  ~TtsPlatformImplMac() override;
-
-  base::scoped_nsobject<SingleUseSpeechSynthesizer> speech_synthesizer_;
-  base::scoped_nsobject<ChromeTtsDelegate> delegate_;
-  int utterance_id_;
-  std::string utterance_;
-  int last_char_index_;
-  bool paused_;
-
-  friend struct base::DefaultSingletonTraits<TtsPlatformImplMac>;
-
-  DISALLOW_COPY_AND_ASSIGN(TtsPlatformImplMac);
-};
-
-// static
-TtsPlatformImpl* TtsPlatformImpl::GetInstance() {
-  return TtsPlatformImplMac::GetInstance();
-}
-
-bool TtsPlatformImplMac::Speak(int utterance_id,
-                               const std::string& utterance,
-                               const std::string& lang,
-                               const VoiceData& voice,
-                               const UtteranceContinuousParameters& params) {
-  // TODO: convert SSML to SAPI xml. http://crbug.com/88072
-  utterance_ = utterance;
-  paused_ = false;
-
-  NSString* utterance_nsstring =
-      [NSString stringWithUTF8String:utterance_.c_str()];
-
-  // Deliberately construct a new speech synthesizer every time Speak is
-  // called, otherwise there's no way to know whether calls to the delegate
-  // apply to the current utterance or a previous utterance. In
-  // experimentation, the overhead of constructing and destructing a
-  // NSSpeechSynthesizer is minimal.
-  speech_synthesizer_.reset([[SingleUseSpeechSynthesizer alloc]
-      initWithUtterance:utterance_nsstring]);
-  [speech_synthesizer_ setDelegate:delegate_];
-
-  if (!voice.native_voice_identifier.empty()) {
-    NSString* native_voice_identifier =
-        [NSString stringWithUTF8String:voice.native_voice_identifier.c_str()];
-    [speech_synthesizer_ setVoice:native_voice_identifier];
-  }
-
-  utterance_id_ = utterance_id;
-
-  // TODO: support languages other than the default: crbug.com/88059
-
-  if (params.rate >= 0.0) {
-    // The TTS api defines rate via words per minute. Let 200 be the default.
-    [speech_synthesizer_ setObject:[NSNumber numberWithInt:params.rate * 200]
-                       forProperty:NSSpeechRateProperty
-                             error:nil];
-  }
-
-  if (params.pitch >= 0.0) {
-    // The input is a float from 0.0 to 2.0, with 1.0 being the default.
-    // Get the default pitch for this voice and modulate it by 50% - 150%.
-    NSError* errorCode;
-    NSNumber* defaultPitchObj =
-        [speech_synthesizer_ objectForProperty:NSSpeechPitchBaseProperty
-                                         error:&errorCode];
-    int defaultPitch = defaultPitchObj ? [defaultPitchObj intValue] : 48;
-    int newPitch = static_cast<int>(defaultPitch * (0.5 * params.pitch + 0.5));
-    [speech_synthesizer_ setObject:[NSNumber numberWithInt:newPitch]
-                       forProperty:NSSpeechPitchBaseProperty
-                             error:nil];
-  }
-
-  if (params.volume >= 0.0) {
-    [speech_synthesizer_ setObject:[NSNumber numberWithFloat:params.volume]
-                       forProperty:NSSpeechVolumeProperty
-                             error:nil];
-  }
-
-  bool success = [speech_synthesizer_ startSpeakingRetainedUtterance];
-  if (success) {
-    TtsController* controller = TtsController::GetInstance();
-    controller->OnTtsEvent(utterance_id_, TTS_EVENT_START, 0, "");
-  }
-  return success;
-}
-
-bool TtsPlatformImplMac::StopSpeaking() {
-  if (speech_synthesizer_.get()) {
-    [speech_synthesizer_ stopSpeaking];
-    speech_synthesizer_.reset(nil);
-  }
-  paused_ = false;
-  return true;
-}
-
-void TtsPlatformImplMac::Pause() {
-  if (speech_synthesizer_.get() && utterance_id_ && !paused_) {
-    [speech_synthesizer_ pauseSpeakingAtBoundary:NSSpeechImmediateBoundary];
-    paused_ = true;
-    TtsController::GetInstance()->OnTtsEvent(utterance_id_, TTS_EVENT_PAUSE,
-                                             last_char_index_, "");
-  }
-}
-
-void TtsPlatformImplMac::Resume() {
-  if (speech_synthesizer_.get() && utterance_id_ && paused_) {
-    [speech_synthesizer_ continueSpeaking];
-    paused_ = false;
-    TtsController::GetInstance()->OnTtsEvent(utterance_id_, TTS_EVENT_RESUME,
-                                             last_char_index_, "");
-  }
-}
-
-bool TtsPlatformImplMac::IsSpeaking() {
-  if (speech_synthesizer_)
-    return [speech_synthesizer_ isSpeaking];
-  return false;
-}
-
-void TtsPlatformImplMac::GetVoices(std::vector<VoiceData>* outVoices) {
-  NSArray* voices = [NSSpeechSynthesizer availableVoices];
-
-  // Create a new temporary array of the available voices with
-  // the default voice first.
-  NSMutableArray* orderedVoices =
-      [NSMutableArray arrayWithCapacity:[voices count]];
-  NSString* defaultVoice = [NSSpeechSynthesizer defaultVoice];
-  if (defaultVoice) {
-    [orderedVoices addObject:defaultVoice];
-  }
-  for (NSString* voiceIdentifier in voices) {
-    if (![voiceIdentifier isEqualToString:defaultVoice])
-      [orderedVoices addObject:voiceIdentifier];
-  }
-
-  for (NSString* voiceIdentifier in orderedVoices) {
-    outVoices->push_back(VoiceData());
-    VoiceData& data = outVoices->back();
-
-    NSDictionary* attributes =
-        [NSSpeechSynthesizer attributesForVoice:voiceIdentifier];
-    NSString* name = [attributes objectForKey:NSVoiceName];
-    NSString* gender = [attributes objectForKey:NSVoiceGender];
-    NSString* localeIdentifier =
-        [attributes objectForKey:NSVoiceLocaleIdentifier];
-
-    data.native = true;
-    data.native_voice_identifier = base::SysNSStringToUTF8(voiceIdentifier);
-    data.name = base::SysNSStringToUTF8(name);
-
-    NSDictionary* localeComponents =
-        [NSLocale componentsFromLocaleIdentifier:localeIdentifier];
-    NSString* language = [localeComponents objectForKey:NSLocaleLanguageCode];
-    NSString* country = [localeComponents objectForKey:NSLocaleCountryCode];
-    if (language && country) {
-      data.lang =
-          [[NSString stringWithFormat:@"%@-%@", language, country] UTF8String];
-    } else {
-      data.lang = base::SysNSStringToUTF8(language);
-    }
-    if ([gender isEqualToString:NSVoiceGenderMale])
-      data.gender = TTS_GENDER_MALE;
-    else if ([gender isEqualToString:NSVoiceGenderFemale])
-      data.gender = TTS_GENDER_FEMALE;
-    else
-      data.gender = TTS_GENDER_NONE;
-    data.events.insert(TTS_EVENT_START);
-    data.events.insert(TTS_EVENT_END);
-    data.events.insert(TTS_EVENT_WORD);
-    data.events.insert(TTS_EVENT_ERROR);
-    data.events.insert(TTS_EVENT_CANCELLED);
-    data.events.insert(TTS_EVENT_INTERRUPTED);
-    data.events.insert(TTS_EVENT_PAUSE);
-    data.events.insert(TTS_EVENT_RESUME);
-  }
-}
-
-void TtsPlatformImplMac::OnSpeechEvent(NSSpeechSynthesizer* sender,
-                                       TtsEventType event_type,
-                                       int char_index,
-                                       const std::string& error_message) {
-  // Don't send events from an utterance that's already completed.
-  // This depends on the fact that we construct a new NSSpeechSynthesizer
-  // each time we call Speak.
-  if (sender != speech_synthesizer_.get())
-    return;
-
-  if (event_type == TTS_EVENT_END)
-    char_index = utterance_.size();
-  TtsController* controller = TtsController::GetInstance();
-  controller->OnTtsEvent(utterance_id_, event_type, char_index, error_message);
-  last_char_index_ = char_index;
-}
-
-TtsPlatformImplMac::TtsPlatformImplMac() {
-  utterance_id_ = -1;
-  paused_ = false;
-
-  delegate_.reset([[ChromeTtsDelegate alloc] initWithPlatformImplMac:this]);
-}
-
-TtsPlatformImplMac::~TtsPlatformImplMac() {}
-
-// static
-TtsPlatformImplMac* TtsPlatformImplMac::GetInstance() {
-  return base::Singleton<TtsPlatformImplMac>::get();
-}
-
-@implementation ChromeTtsDelegate
-
-- (id)initWithPlatformImplMac:(TtsPlatformImplMac*)ttsImplMac {
-  if ((self = [super init])) {
-    ttsImplMac_ = ttsImplMac;
-  }
-  return self;
-}
-
-- (void)speechSynthesizer:(NSSpeechSynthesizer*)sender
-        didFinishSpeaking:(BOOL)finished_speaking {
-  ttsImplMac_->OnSpeechEvent(sender, TTS_EVENT_END, 0, "");
-}
-
-- (void)speechSynthesizer:(NSSpeechSynthesizer*)sender
-            willSpeakWord:(NSRange)character_range
-                 ofString:(NSString*)string {
-  ttsImplMac_->OnSpeechEvent(sender, TTS_EVENT_WORD, character_range.location,
-                             "");
-}
-
-- (void)speechSynthesizer:(NSSpeechSynthesizer*)sender
-    didEncounterErrorAtIndex:(NSUInteger)character_index
-                    ofString:(NSString*)string
-                     message:(NSString*)message {
-  std::string message_utf8 = base::SysNSStringToUTF8(message);
-  ttsImplMac_->OnSpeechEvent(sender, TTS_EVENT_ERROR, character_index,
-                             message_utf8);
-}
-
-@end
-
-@implementation SingleUseSpeechSynthesizer
-
-- (id)initWithUtterance:(NSString*)utterance {
-  self = [super init];
-  if (self) {
-    utterance_.reset([utterance retain]);
-    didSpeak_ = false;
-  }
-  return self;
-}
-
-- (bool)startSpeakingRetainedUtterance {
-  CHECK(!didSpeak_);
-  CHECK(utterance_);
-  didSpeak_ = true;
-  return [super startSpeakingString:utterance_];
-}
-
-- (bool)startSpeakingString:(NSString*)utterance {
-  CHECK(false);
-  return false;
-}
-
-@end

+ 0 - 176
chromium_src/chrome/browser/speech/tts_message_filter.cc

@@ -1,176 +0,0 @@
-// Copyright (c) 2013 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 "chrome/browser/speech/tts_message_filter.h"
-
-#include "base/bind.h"
-#include "base/logging.h"
-#include "content/public/browser/browser_context.h"
-#include "content/public/browser/render_process_host.h"
-
-using content::BrowserThread;
-
-TtsMessageFilter::TtsMessageFilter(int render_process_id,
-                                   content::BrowserContext* browser_context)
-    : BrowserMessageFilter(TtsMsgStart),
-      render_process_id_(render_process_id),
-      browser_context_(browser_context),
-      weak_ptr_factory_(this) {
-  CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  TtsController::GetInstance()->AddVoicesChangedDelegate(this);
-
-  // Balanced in OnChannelClosingInUIThread() to keep the ref-count be non-zero
-  // until all WeakPtr's are invalidated.
-  AddRef();
-}
-
-void TtsMessageFilter::OverrideThreadForMessage(const IPC::Message& message,
-                                                BrowserThread::ID* thread) {
-  switch (message.type()) {
-    case TtsHostMsg_InitializeVoiceList::ID:
-    case TtsHostMsg_Speak::ID:
-    case TtsHostMsg_Pause::ID:
-    case TtsHostMsg_Resume::ID:
-    case TtsHostMsg_Cancel::ID:
-      *thread = BrowserThread::UI;
-      break;
-  }
-}
-
-bool TtsMessageFilter::OnMessageReceived(const IPC::Message& message) {
-  bool handled = true;
-  IPC_BEGIN_MESSAGE_MAP(TtsMessageFilter, message)
-    IPC_MESSAGE_HANDLER(TtsHostMsg_InitializeVoiceList, OnInitializeVoiceList)
-    IPC_MESSAGE_HANDLER(TtsHostMsg_Speak, OnSpeak)
-    IPC_MESSAGE_HANDLER(TtsHostMsg_Pause, OnPause)
-    IPC_MESSAGE_HANDLER(TtsHostMsg_Resume, OnResume)
-    IPC_MESSAGE_HANDLER(TtsHostMsg_Cancel, OnCancel)
-    IPC_MESSAGE_UNHANDLED(handled = false)
-  IPC_END_MESSAGE_MAP()
-  return handled;
-}
-
-void TtsMessageFilter::OnChannelClosing() {
-  BrowserThread::PostTask(
-      BrowserThread::UI, FROM_HERE,
-      base::Bind(&TtsMessageFilter::OnChannelClosingInUIThread, this));
-}
-
-void TtsMessageFilter::OnDestruct() const {
-  BrowserThread::DeleteOnUIThread::Destruct(this);
-}
-
-void TtsMessageFilter::OnInitializeVoiceList() {
-  CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  TtsController* tts_controller = TtsController::GetInstance();
-  std::vector<VoiceData> voices;
-  tts_controller->GetVoices(browser_context_, &voices);
-
-  std::vector<TtsVoice> out_voices;
-  out_voices.resize(voices.size());
-  for (size_t i = 0; i < voices.size(); ++i) {
-    TtsVoice& out_voice = out_voices[i];
-    out_voice.voice_uri = voices[i].name;
-    out_voice.name = voices[i].name;
-    out_voice.lang = voices[i].lang;
-    out_voice.local_service = !voices[i].remote;
-    out_voice.is_default = (i == 0);
-  }
-  Send(new TtsMsg_SetVoiceList(out_voices));
-}
-
-void TtsMessageFilter::OnSpeak(const TtsUtteranceRequest& request) {
-  CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-
-  std::unique_ptr<Utterance> utterance(new Utterance(browser_context_));
-  utterance->set_src_id(request.id);
-  utterance->set_text(request.text);
-  utterance->set_lang(request.lang);
-  utterance->set_voice_name(request.voice);
-  utterance->set_can_enqueue(true);
-
-  UtteranceContinuousParameters params;
-  params.rate = request.rate;
-  params.pitch = request.pitch;
-  params.volume = request.volume;
-  utterance->set_continuous_parameters(params);
-
-  utterance->set_event_delegate(weak_ptr_factory_.GetWeakPtr());
-
-  TtsController::GetInstance()->SpeakOrEnqueue(utterance.release());
-}
-
-void TtsMessageFilter::OnPause() {
-  CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  TtsController::GetInstance()->Pause();
-}
-
-void TtsMessageFilter::OnResume() {
-  CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  TtsController::GetInstance()->Resume();
-}
-
-void TtsMessageFilter::OnCancel() {
-  CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  TtsController::GetInstance()->Stop();
-}
-
-void TtsMessageFilter::OnTtsEvent(Utterance* utterance,
-                                  TtsEventType event_type,
-                                  int char_index,
-                                  const std::string& error_message) {
-  CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  switch (event_type) {
-    case TTS_EVENT_START:
-      Send(new TtsMsg_DidStartSpeaking(utterance->src_id()));
-      break;
-    case TTS_EVENT_END:
-      Send(new TtsMsg_DidFinishSpeaking(utterance->src_id()));
-      break;
-    case TTS_EVENT_WORD:
-      Send(new TtsMsg_WordBoundary(utterance->src_id(), char_index));
-      break;
-    case TTS_EVENT_SENTENCE:
-      Send(new TtsMsg_SentenceBoundary(utterance->src_id(), char_index));
-      break;
-    case TTS_EVENT_MARKER:
-      Send(new TtsMsg_MarkerEvent(utterance->src_id(), char_index));
-      break;
-    case TTS_EVENT_INTERRUPTED:
-      Send(new TtsMsg_WasInterrupted(utterance->src_id()));
-      break;
-    case TTS_EVENT_CANCELLED:
-      Send(new TtsMsg_WasCancelled(utterance->src_id()));
-      break;
-    case TTS_EVENT_ERROR:
-      Send(
-          new TtsMsg_SpeakingErrorOccurred(utterance->src_id(), error_message));
-      break;
-    case TTS_EVENT_PAUSE:
-      Send(new TtsMsg_DidPauseSpeaking(utterance->src_id()));
-      break;
-    case TTS_EVENT_RESUME:
-      Send(new TtsMsg_DidResumeSpeaking(utterance->src_id()));
-      break;
-  }
-}
-
-void TtsMessageFilter::OnVoicesChanged() {
-  CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  OnInitializeVoiceList();
-}
-
-void TtsMessageFilter::OnChannelClosingInUIThread() {
-  CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  TtsController::GetInstance()->RemoveVoicesChangedDelegate(this);
-
-  weak_ptr_factory_.InvalidateWeakPtrs();
-  Release();  // Balanced in TtsMessageFilter().
-}
-
-TtsMessageFilter::~TtsMessageFilter() {
-  CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  DCHECK(!weak_ptr_factory_.HasWeakPtrs());
-  TtsController::GetInstance()->RemoveVoicesChangedDelegate(this);
-}

+ 0 - 62
chromium_src/chrome/browser/speech/tts_message_filter.h

@@ -1,62 +0,0 @@
-// Copyright (c) 2013 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 CHROME_BROWSER_SPEECH_TTS_MESSAGE_FILTER_H_
-#define CHROME_BROWSER_SPEECH_TTS_MESSAGE_FILTER_H_
-
-#include "base/memory/weak_ptr.h"
-#include "chrome/browser/speech/tts_controller.h"
-#include "chrome/common/tts_messages.h"
-#include "content/public/browser/browser_message_filter.h"
-
-namespace content {
-class BrowserContext;
-}
-
-class TtsMessageFilter : public content::BrowserMessageFilter,
-                         public UtteranceEventDelegate,
-                         public VoicesChangedDelegate {
- public:
-  explicit TtsMessageFilter(int render_process_id,
-                            content::BrowserContext* browser_context);
-
-  // content::BrowserMessageFilter implementation.
-  void OverrideThreadForMessage(const IPC::Message& message,
-                                content::BrowserThread::ID* thread) override;
-  bool OnMessageReceived(const IPC::Message& message) override;
-  void OnChannelClosing() override;
-  void OnDestruct() const override;
-
-  // UtteranceEventDelegate implementation.
-  void OnTtsEvent(Utterance* utterance,
-                  TtsEventType event_type,
-                  int char_index,
-                  const std::string& error_message) override;
-
-  // VoicesChangedDelegate implementation.
-  void OnVoicesChanged() override;
-
- private:
-  friend class content::BrowserThread;
-  friend class base::DeleteHelper<TtsMessageFilter>;
-
-  ~TtsMessageFilter() override;
-
-  void OnInitializeVoiceList();
-  void OnSpeak(const TtsUtteranceRequest& utterance);
-  void OnPause();
-  void OnResume();
-  void OnCancel();
-
-  void OnChannelClosingInUIThread();
-
-  int render_process_id_;
-  content::BrowserContext* browser_context_;
-
-  base::WeakPtrFactory<TtsMessageFilter> weak_ptr_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(TtsMessageFilter);
-};
-
-#endif  // CHROME_BROWSER_SPEECH_TTS_MESSAGE_FILTER_H_

+ 0 - 28
chromium_src/chrome/browser/speech/tts_platform.cc

@@ -1,28 +0,0 @@
-// Copyright (c) 2012 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 "chrome/browser/speech/tts_platform.h"
-
-#include <string>
-
-bool TtsPlatformImpl::LoadBuiltInTtsExtension(
-    content::BrowserContext* browser_context) {
-  return false;
-}
-
-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) {
-}

+ 0 - 80
chromium_src/chrome/browser/speech/tts_platform.h

@@ -1,80 +0,0 @@
-// Copyright (c) 2012 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 CHROME_BROWSER_SPEECH_TTS_PLATFORM_H_
-#define CHROME_BROWSER_SPEECH_TTS_PLATFORM_H_
-
-#include <string>
-
-#include "chrome/browser/speech/tts_controller.h"
-
-// Abstract class that defines the native platform TTS interface,
-// subclassed by specific implementations on Win, Mac, etc.
-class TtsPlatformImpl {
- public:
-  static TtsPlatformImpl* GetInstance();
-
-  // Returns true if this platform implementation is supported and available.
-  virtual bool PlatformImplAvailable() = 0;
-
-  // Some platforms may provide a built-in TTS extension. Returns true
-  // if the extension was not previously loaded and is now loading, and
-  // false if it's already loaded or if there's no extension to load.
-  // Will call TtsController::RetrySpeakingQueuedUtterances when
-  // the extension finishes loading.
-  virtual bool LoadBuiltInTtsExtension(
-      content::BrowserContext* browser_context);
-
-  // 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:
-  TtsPlatformImpl() {}
-
-  // On some platforms this may be a leaky singleton - do not rely on the
-  // destructor being called!  http://crbug.com/122026
-  virtual ~TtsPlatformImpl() {}
-
-  std::string error_;
-
-  DISALLOW_COPY_AND_ASSIGN(TtsPlatformImpl);
-};
-
-#endif  // CHROME_BROWSER_SPEECH_TTS_PLATFORM_H_

+ 0 - 311
chromium_src/chrome/browser/speech/tts_win.cc

@@ -1,311 +0,0 @@
-// Copyright (c) 2012 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 <math.h>
-#include <objbase.h>
-#include <sapi.h>
-#include <sphelper.h>
-#include <wrl/client.h>
-
-#include "base/memory/singleton.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/utf_string_conversions.h"
-#include "base/values.h"
-#include "base/win/scoped_co_mem.h"
-#include "chrome/browser/speech/tts_controller.h"
-#include "chrome/browser/speech/tts_platform.h"
-
-namespace {
-// ISpObjectToken key and value names.
-const wchar_t kAttributesKey[] = L"Attributes";
-const wchar_t kGenderValue[] = L"Gender";
-const wchar_t kLanguageValue[] = L"Language";
-}  // anonymous namespace.
-
-class TtsPlatformImplWin : public TtsPlatformImpl {
- public:
-  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;
-
-  bool StopSpeaking() override;
-
-  void Pause() override;
-
-  void Resume() override;
-
-  bool IsSpeaking() override;
-
-  void GetVoices(std::vector<VoiceData>* out_voices) override;
-
-  // Get the single instance of this class.
-  static TtsPlatformImplWin* GetInstance();
-
-  static void __stdcall SpeechEventCallback(WPARAM w_param, LPARAM l_param);
-
- private:
-  TtsPlatformImplWin();
-  ~TtsPlatformImplWin() override {}
-
-  void OnSpeechEvent();
-  void SetVoiceFromName(const std::string& name);
-  Microsoft::WRL::ComPtr<ISpVoice> speech_synthesizer_;
-
-  // These apply to the current utterance only.
-  std::wstring utterance_;
-  int utterance_id_;
-  int prefix_len_;
-  ULONG stream_number_;
-  int char_position_;
-  bool paused_;
-  std::string last_voice_name_;
-  friend struct base::DefaultSingletonTraits<TtsPlatformImplWin>;
-
-  DISALLOW_COPY_AND_ASSIGN(TtsPlatformImplWin);
-};
-
-// static
-TtsPlatformImpl* TtsPlatformImpl::GetInstance() {
-  return TtsPlatformImplWin::GetInstance();
-}
-
-bool TtsPlatformImplWin::Speak(int utterance_id,
-                               const std::string& src_utterance,
-                               const std::string& lang,
-                               const VoiceData& voice,
-                               const UtteranceContinuousParameters& params) {
-  std::wstring prefix;
-  std::wstring suffix;
-
-  if (!speech_synthesizer_.Get())
-    return false;
-  SetVoiceFromName(voice.name);
-  if (params.rate >= 0.0) {
-    // Map our multiplicative range of 0.1x to 10.0x onto Microsoft's
-    // linear range of -10 to 10:
-    //   0.1 -> -10
-    //   1.0 -> 0
-    //  10.0 -> 10
-    speech_synthesizer_->SetRate(static_cast<int32_t>(10 * log10(params.rate)));
-  }
-
-  if (params.pitch >= 0.0) {
-    // The TTS api allows a range of -10 to 10 for speech pitch.
-    // TODO(dtseng): cleanup if we ever use any other properties that
-    // require xml.
-    std::wstring pitch_value =
-        base::IntToString16(static_cast<int>(params.pitch * 10 - 10));
-    prefix = L"<pitch absmiddle=\"" + pitch_value + L"\">";
-    suffix = L"</pitch>";
-  }
-
-  if (params.volume >= 0.0) {
-    // The TTS api allows a range of 0 to 100 for speech volume.
-    speech_synthesizer_->SetVolume(static_cast<uint16_t>(params.volume * 100));
-  }
-
-  // TODO(dmazzoni): convert SSML to SAPI xml. http://crbug.com/88072
-
-  utterance_ = base::UTF8ToWide(src_utterance);
-  utterance_id_ = utterance_id;
-  char_position_ = 0;
-  std::wstring merged_utterance = prefix + utterance_ + suffix;
-  prefix_len_ = prefix.size();
-
-  HRESULT result = speech_synthesizer_->Speak(merged_utterance.c_str(),
-                                              SPF_ASYNC, &stream_number_);
-  return (result == S_OK);
-}
-
-bool TtsPlatformImplWin::StopSpeaking() {
-  if (speech_synthesizer_.Get()) {
-    // Clear the stream number so that any further events relating to this
-    // utterance are ignored.
-    stream_number_ = 0;
-
-    if (IsSpeaking()) {
-      // Stop speech by speaking the empty string with the purge flag.
-      speech_synthesizer_->Speak(L"", SPF_ASYNC | SPF_PURGEBEFORESPEAK, NULL);
-    }
-    if (paused_) {
-      speech_synthesizer_->Resume();
-      paused_ = false;
-    }
-  }
-  return true;
-}
-
-void TtsPlatformImplWin::Pause() {
-  if (speech_synthesizer_.Get() && utterance_id_ && !paused_) {
-    speech_synthesizer_->Pause();
-    paused_ = true;
-    TtsController::GetInstance()->OnTtsEvent(utterance_id_, TTS_EVENT_PAUSE,
-                                             char_position_, "");
-  }
-}
-
-void TtsPlatformImplWin::Resume() {
-  if (speech_synthesizer_.Get() && utterance_id_ && paused_) {
-    speech_synthesizer_->Resume();
-    paused_ = false;
-    TtsController::GetInstance()->OnTtsEvent(utterance_id_, TTS_EVENT_RESUME,
-                                             char_position_, "");
-  }
-}
-
-bool TtsPlatformImplWin::IsSpeaking() {
-  if (speech_synthesizer_.Get()) {
-    SPVOICESTATUS status;
-    HRESULT result = speech_synthesizer_->GetStatus(&status, NULL);
-    if (result == S_OK) {
-      if (status.dwRunningState == 0 ||  // 0 == waiting to speak
-          status.dwRunningState == SPRS_IS_SPEAKING) {
-        return true;
-      }
-    }
-  }
-  return false;
-}
-
-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()))
-    return;
-  if (S_OK != voice_tokens->GetCount(&voice_count))
-    return;
-  for (unsigned i = 0; i < voice_count; i++) {
-    VoiceData voice;
-    Microsoft::WRL::ComPtr<ISpObjectToken> voice_token;
-    if (S_OK != voice_tokens->Next(1, voice_token.GetAddressOf(), NULL))
-      return;
-    base::win::ScopedCoMem<WCHAR> description;
-    if (S_OK != SpGetDescription(voice_token.Get(), &description))
-      continue;
-    voice.name = base::WideToUTF8(description.get());
-    Microsoft::WRL::ComPtr<ISpDataKey> attributes;
-    if (S_OK != voice_token->OpenKey(kAttributesKey, attributes.GetAddressOf()))
-      continue;
-    base::win::ScopedCoMem<WCHAR> gender;
-    if (S_OK == attributes->GetStringValue(kGenderValue, &gender)) {
-      if (0 == _wcsicmp(gender.get(), L"male"))
-        voice.gender = TTS_GENDER_MALE;
-      else if (0 == _wcsicmp(gender.get(), L"female"))
-        voice.gender = TTS_GENDER_FEMALE;
-    }
-    base::win::ScopedCoMem<WCHAR> language;
-    if (S_OK == attributes->GetStringValue(kLanguageValue, &language)) {
-      int lcid_value;
-      base::HexStringToInt(base::WideToUTF8(language.get()), &lcid_value);
-      LCID lcid = MAKELCID(lcid_value, SORT_DEFAULT);
-      WCHAR locale_name[LOCALE_NAME_MAX_LENGTH] = {0};
-      LCIDToLocaleName(lcid, locale_name, LOCALE_NAME_MAX_LENGTH, 0);
-      voice.lang = base::WideToUTF8(locale_name);
-    }
-    voice.native = true;
-    voice.events.insert(TTS_EVENT_START);
-    voice.events.insert(TTS_EVENT_END);
-    voice.events.insert(TTS_EVENT_MARKER);
-    voice.events.insert(TTS_EVENT_WORD);
-    voice.events.insert(TTS_EVENT_SENTENCE);
-    voice.events.insert(TTS_EVENT_PAUSE);
-    voice.events.insert(TTS_EVENT_RESUME);
-    out_voices->push_back(voice);
-  }
-}
-
-void TtsPlatformImplWin::OnSpeechEvent() {
-  TtsController* controller = TtsController::GetInstance();
-  SPEVENT event;
-  while (S_OK == speech_synthesizer_->GetEvents(1, &event, NULL)) {
-    if (event.ulStreamNum != stream_number_)
-      continue;
-
-    switch (event.eEventId) {
-      case SPEI_START_INPUT_STREAM:
-        controller->OnTtsEvent(utterance_id_, TTS_EVENT_START, 0,
-                               std::string());
-        break;
-      case SPEI_END_INPUT_STREAM:
-        char_position_ = utterance_.size();
-        controller->OnTtsEvent(utterance_id_, TTS_EVENT_END, char_position_,
-                               std::string());
-        break;
-      case SPEI_TTS_BOOKMARK:
-        controller->OnTtsEvent(utterance_id_, TTS_EVENT_MARKER, char_position_,
-                               std::string());
-        break;
-      case SPEI_WORD_BOUNDARY:
-        char_position_ = static_cast<ULONG>(event.lParam) - prefix_len_;
-        controller->OnTtsEvent(utterance_id_, TTS_EVENT_WORD, char_position_,
-                               std::string());
-        break;
-      case SPEI_SENTENCE_BOUNDARY:
-        char_position_ = static_cast<ULONG>(event.lParam) - prefix_len_;
-        controller->OnTtsEvent(utterance_id_, TTS_EVENT_SENTENCE,
-                               char_position_, std::string());
-        break;
-      default:
-        break;
-    }
-  }
-}
-void TtsPlatformImplWin::SetVoiceFromName(const std::string& name) {
-  if (name.empty() || name == last_voice_name_)
-    return;
-  last_voice_name_ = name;
-  Microsoft::WRL::ComPtr<IEnumSpObjectTokens> voice_tokens;
-  unsigned long voice_count;
-  if (S_OK !=
-      SpEnumTokens(SPCAT_VOICES, NULL, NULL, voice_tokens.GetAddressOf()))
-    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))
-      return;
-    base::win::ScopedCoMem<WCHAR> description;
-    if (S_OK != SpGetDescription(voice_token.Get(), &description))
-      continue;
-    if (name == base::WideToUTF8(description.get())) {
-      speech_synthesizer_->SetVoice(voice_token.Get());
-      break;
-    }
-  }
-}
-TtsPlatformImplWin::TtsPlatformImplWin()
-    : utterance_id_(0),
-      prefix_len_(0),
-      stream_number_(0),
-      char_position_(0),
-      paused_(false) {
-  ::CoCreateInstance(CLSID_SpVoice, nullptr, CLSCTX_ALL,
-                     IID_PPV_ARGS(&speech_synthesizer_));
-  if (speech_synthesizer_.Get()) {
-    ULONGLONG event_mask =
-        SPFEI(SPEI_START_INPUT_STREAM) | SPFEI(SPEI_TTS_BOOKMARK) |
-        SPFEI(SPEI_WORD_BOUNDARY) | SPFEI(SPEI_SENTENCE_BOUNDARY) |
-        SPFEI(SPEI_END_INPUT_STREAM);
-    speech_synthesizer_->SetInterest(event_mask, event_mask);
-    speech_synthesizer_->SetNotifyCallbackFunction(
-        TtsPlatformImplWin::SpeechEventCallback, 0, 0);
-  }
-}
-
-// static
-TtsPlatformImplWin* TtsPlatformImplWin::GetInstance() {
-  return base::Singleton<TtsPlatformImplWin,
-                         base::LeakySingletonTraits<TtsPlatformImplWin>>::get();
-}
-
-// static
-void TtsPlatformImplWin::SpeechEventCallback(WPARAM w_param, LPARAM l_param) {
-  GetInstance()->OnSpeechEvent();
-}

+ 0 - 61
chromium_src/chrome/common/tts_messages.h

@@ -1,61 +0,0 @@
-// Copyright (c) 2013 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.
-
-// Multiply-included message file, hence no include guard.
-
-#include <vector>
-
-#include "chrome/common/tts_utterance_request.h"
-#include "ipc/ipc_message_macros.h"
-#include "ipc/ipc_param_traits.h"
-
-#define IPC_MESSAGE_START TtsMsgStart
-
-IPC_STRUCT_TRAITS_BEGIN(TtsUtteranceRequest)
-  IPC_STRUCT_TRAITS_MEMBER(id)
-  IPC_STRUCT_TRAITS_MEMBER(text)
-  IPC_STRUCT_TRAITS_MEMBER(lang)
-  IPC_STRUCT_TRAITS_MEMBER(voice)
-  IPC_STRUCT_TRAITS_MEMBER(volume)
-  IPC_STRUCT_TRAITS_MEMBER(rate)
-  IPC_STRUCT_TRAITS_MEMBER(pitch)
-IPC_STRUCT_TRAITS_END()
-
-IPC_STRUCT_TRAITS_BEGIN(TtsVoice)
-  IPC_STRUCT_TRAITS_MEMBER(voice_uri)
-  IPC_STRUCT_TRAITS_MEMBER(name)
-  IPC_STRUCT_TRAITS_MEMBER(lang)
-  IPC_STRUCT_TRAITS_MEMBER(local_service)
-  IPC_STRUCT_TRAITS_MEMBER(is_default)
-IPC_STRUCT_TRAITS_END()
-
-// Renderer -> Browser messages.
-
-IPC_MESSAGE_CONTROL0(TtsHostMsg_InitializeVoiceList)
-IPC_MESSAGE_CONTROL1(TtsHostMsg_Speak, TtsUtteranceRequest)
-IPC_MESSAGE_CONTROL0(TtsHostMsg_Pause)
-IPC_MESSAGE_CONTROL0(TtsHostMsg_Resume)
-IPC_MESSAGE_CONTROL0(TtsHostMsg_Cancel)
-
-// Browser -> Renderer messages.
-
-IPC_MESSAGE_CONTROL1(TtsMsg_SetVoiceList, std::vector<TtsVoice>)
-IPC_MESSAGE_CONTROL1(TtsMsg_DidStartSpeaking, int /* utterance id */)
-IPC_MESSAGE_CONTROL1(TtsMsg_DidFinishSpeaking, int /* utterance id */)
-IPC_MESSAGE_CONTROL1(TtsMsg_DidPauseSpeaking, int /* utterance id */)
-IPC_MESSAGE_CONTROL1(TtsMsg_DidResumeSpeaking, int /* utterance id */)
-IPC_MESSAGE_CONTROL2(TtsMsg_WordBoundary,
-                     int /* utterance id */,
-                     int /* char index */)
-IPC_MESSAGE_CONTROL2(TtsMsg_SentenceBoundary,
-                     int /* utterance id */,
-                     int /* char index */)
-IPC_MESSAGE_CONTROL2(TtsMsg_MarkerEvent,
-                     int /* utterance id */,
-                     int /* char index */)
-IPC_MESSAGE_CONTROL1(TtsMsg_WasInterrupted, int /* utterance id */)
-IPC_MESSAGE_CONTROL1(TtsMsg_WasCancelled, int /* utterance id */)
-IPC_MESSAGE_CONTROL2(TtsMsg_SpeakingErrorOccurred,
-                     int /* utterance id */,
-                     std::string /* error message */)

+ 0 - 20
chromium_src/chrome/common/tts_utterance_request.cc

@@ -1,20 +0,0 @@
-// Copyright (c) 2013 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 "chrome/common/tts_utterance_request.h"
-
-TtsUtteranceRequest::TtsUtteranceRequest()
-    : id(0), volume(1.0), rate(1.0), pitch(1.0) {}
-
-TtsUtteranceRequest::~TtsUtteranceRequest() {}
-
-TtsVoice::TtsVoice() : local_service(true), is_default(false) {}
-
-TtsVoice::TtsVoice(const TtsVoice&) = default;
-
-TtsVoice::~TtsVoice() {}
-
-TtsUtteranceResponse::TtsUtteranceResponse() : id(0) {}
-
-TtsUtteranceResponse::~TtsUtteranceResponse() {}

+ 0 - 45
chromium_src/chrome/common/tts_utterance_request.h

@@ -1,45 +0,0 @@
-// Copyright (c) 2013 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 CHROME_COMMON_TTS_UTTERANCE_REQUEST_H_
-#define CHROME_COMMON_TTS_UTTERANCE_REQUEST_H_
-
-#include <vector>
-
-#include "base/macros.h"
-#include "base/strings/string16.h"
-
-struct TtsUtteranceRequest {
-  TtsUtteranceRequest();
-  ~TtsUtteranceRequest();
-
-  int id;
-  std::string text;
-  std::string lang;
-  std::string voice;
-  float volume;
-  float rate;
-  float pitch;
-};
-
-struct TtsVoice {
-  TtsVoice();
-  TtsVoice(const TtsVoice&);
-  ~TtsVoice();
-
-  std::string voice_uri;
-  std::string name;
-  std::string lang;
-  bool local_service;
-  bool is_default;
-};
-
-struct TtsUtteranceResponse {
-  TtsUtteranceResponse();
-  ~TtsUtteranceResponse();
-
-  int id;
-};
-
-#endif  // CHROME_COMMON_TTS_UTTERANCE_REQUEST_H_

+ 0 - 198
chromium_src/chrome/renderer/tts_dispatcher.cc

@@ -1,198 +0,0 @@
-// Copyright (c) 2013 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 "chrome/renderer/tts_dispatcher.h"
-
-#include "base/strings/utf_string_conversions.h"
-#include "chrome/common/tts_messages.h"
-#include "chrome/common/tts_utterance_request.h"
-#include "content/public/renderer/render_thread.h"
-#include "third_party/blink/public/platform/web_speech_synthesis_utterance.h"
-#include "third_party/blink/public/platform/web_speech_synthesis_voice.h"
-#include "third_party/blink/public/platform/web_string.h"
-#include "third_party/blink/public/platform/web_vector.h"
-
-using blink::WebSpeechSynthesisUtterance;
-using blink::WebSpeechSynthesisVoice;
-using blink::WebSpeechSynthesizerClient;
-using blink::WebString;
-using blink::WebVector;
-using content::RenderThread;
-
-int TtsDispatcher::next_utterance_id_ = 1;
-
-TtsDispatcher::TtsDispatcher(WebSpeechSynthesizerClient* client)
-    : synthesizer_client_(client) {
-  RenderThread::Get()->AddObserver(this);
-}
-
-TtsDispatcher::~TtsDispatcher() {
-  RenderThread::Get()->RemoveObserver(this);
-}
-
-bool TtsDispatcher::OnControlMessageReceived(const IPC::Message& message) {
-  IPC_BEGIN_MESSAGE_MAP(TtsDispatcher, message)
-    IPC_MESSAGE_HANDLER(TtsMsg_SetVoiceList, OnSetVoiceList)
-    IPC_MESSAGE_HANDLER(TtsMsg_DidStartSpeaking, OnDidStartSpeaking)
-    IPC_MESSAGE_HANDLER(TtsMsg_DidFinishSpeaking, OnDidFinishSpeaking)
-    IPC_MESSAGE_HANDLER(TtsMsg_DidPauseSpeaking, OnDidPauseSpeaking)
-    IPC_MESSAGE_HANDLER(TtsMsg_DidResumeSpeaking, OnDidResumeSpeaking)
-    IPC_MESSAGE_HANDLER(TtsMsg_WordBoundary, OnWordBoundary)
-    IPC_MESSAGE_HANDLER(TtsMsg_SentenceBoundary, OnSentenceBoundary)
-    IPC_MESSAGE_HANDLER(TtsMsg_MarkerEvent, OnMarkerEvent)
-    IPC_MESSAGE_HANDLER(TtsMsg_WasInterrupted, OnWasInterrupted)
-    IPC_MESSAGE_HANDLER(TtsMsg_WasCancelled, OnWasCancelled)
-    IPC_MESSAGE_HANDLER(TtsMsg_SpeakingErrorOccurred, OnSpeakingErrorOccurred)
-  IPC_END_MESSAGE_MAP()
-
-  // Always return false because there may be multiple TtsDispatchers
-  // and we want them all to have a chance to handle this message.
-  return false;
-}
-
-void TtsDispatcher::UpdateVoiceList() {
-  RenderThread::Get()->Send(new TtsHostMsg_InitializeVoiceList());
-}
-
-void TtsDispatcher::Speak(const WebSpeechSynthesisUtterance& web_utterance) {
-  int id = next_utterance_id_++;
-
-  utterance_id_map_[id] = web_utterance;
-
-  TtsUtteranceRequest utterance;
-  utterance.id = id;
-  utterance.text = web_utterance.GetText().Utf8();
-  utterance.lang = web_utterance.Lang().Utf8();
-  utterance.voice = web_utterance.Voice().Utf8();
-  utterance.volume = web_utterance.Volume();
-  utterance.rate = web_utterance.Rate();
-  utterance.pitch = web_utterance.Pitch();
-  RenderThread::Get()->Send(new TtsHostMsg_Speak(utterance));
-}
-
-void TtsDispatcher::Pause() {
-  RenderThread::Get()->Send(new TtsHostMsg_Pause());
-}
-
-void TtsDispatcher::Resume() {
-  RenderThread::Get()->Send(new TtsHostMsg_Resume());
-}
-
-void TtsDispatcher::Cancel() {
-  RenderThread::Get()->Send(new TtsHostMsg_Cancel());
-}
-
-WebSpeechSynthesisUtterance TtsDispatcher::FindUtterance(int utterance_id) {
-  base::hash_map<int, WebSpeechSynthesisUtterance>::const_iterator iter =
-      utterance_id_map_.find(utterance_id);
-  if (iter == utterance_id_map_.end())
-    return WebSpeechSynthesisUtterance();
-  return iter->second;
-}
-
-void TtsDispatcher::OnSetVoiceList(const std::vector<TtsVoice>& voices) {
-  WebVector<WebSpeechSynthesisVoice> out_voices(voices.size());
-  for (size_t i = 0; i < voices.size(); ++i) {
-    out_voices[i] = WebSpeechSynthesisVoice();
-    out_voices[i].SetVoiceURI(WebString::FromUTF8(voices[i].voice_uri));
-    out_voices[i].SetName(WebString::FromUTF8(voices[i].name));
-    out_voices[i].SetLanguage(WebString::FromUTF8(voices[i].lang));
-    out_voices[i].SetIsLocalService(voices[i].local_service);
-    out_voices[i].SetIsDefault(voices[i].is_default);
-  }
-  synthesizer_client_->SetVoiceList(out_voices);
-}
-
-void TtsDispatcher::OnDidStartSpeaking(int utterance_id) {
-  if (utterance_id_map_.find(utterance_id) == utterance_id_map_.end())
-    return;
-
-  WebSpeechSynthesisUtterance utterance = FindUtterance(utterance_id);
-  if (utterance.IsNull())
-    return;
-
-  synthesizer_client_->DidStartSpeaking(utterance);
-}
-
-void TtsDispatcher::OnDidFinishSpeaking(int utterance_id) {
-  WebSpeechSynthesisUtterance utterance = FindUtterance(utterance_id);
-  if (utterance.IsNull())
-    return;
-
-  synthesizer_client_->DidFinishSpeaking(utterance);
-  utterance_id_map_.erase(utterance_id);
-}
-
-void TtsDispatcher::OnDidPauseSpeaking(int utterance_id) {
-  WebSpeechSynthesisUtterance utterance = FindUtterance(utterance_id);
-  if (utterance.IsNull())
-    return;
-
-  synthesizer_client_->DidPauseSpeaking(utterance);
-}
-
-void TtsDispatcher::OnDidResumeSpeaking(int utterance_id) {
-  WebSpeechSynthesisUtterance utterance = FindUtterance(utterance_id);
-  if (utterance.IsNull())
-    return;
-
-  synthesizer_client_->DidResumeSpeaking(utterance);
-}
-
-void TtsDispatcher::OnWordBoundary(int utterance_id, int char_index) {
-  CHECK(char_index >= 0);
-
-  WebSpeechSynthesisUtterance utterance = FindUtterance(utterance_id);
-  if (utterance.IsNull())
-    return;
-
-  synthesizer_client_->WordBoundaryEventOccurred(
-      utterance, static_cast<unsigned>(char_index));
-}
-
-void TtsDispatcher::OnSentenceBoundary(int utterance_id, int char_index) {
-  CHECK(char_index >= 0);
-
-  WebSpeechSynthesisUtterance utterance = FindUtterance(utterance_id);
-  if (utterance.IsNull())
-    return;
-
-  synthesizer_client_->SentenceBoundaryEventOccurred(
-      utterance, static_cast<unsigned>(char_index));
-}
-
-void TtsDispatcher::OnMarkerEvent(int utterance_id, int char_index) {
-  // Not supported yet.
-}
-
-void TtsDispatcher::OnWasInterrupted(int utterance_id) {
-  WebSpeechSynthesisUtterance utterance = FindUtterance(utterance_id);
-  if (utterance.IsNull())
-    return;
-
-  // The web speech API doesn't support "interrupted".
-  synthesizer_client_->DidFinishSpeaking(utterance);
-  utterance_id_map_.erase(utterance_id);
-}
-
-void TtsDispatcher::OnWasCancelled(int utterance_id) {
-  WebSpeechSynthesisUtterance utterance = FindUtterance(utterance_id);
-  if (utterance.IsNull())
-    return;
-
-  // The web speech API doesn't support "cancelled".
-  synthesizer_client_->DidFinishSpeaking(utterance);
-  utterance_id_map_.erase(utterance_id);
-}
-
-void TtsDispatcher::OnSpeakingErrorOccurred(int utterance_id,
-                                            const std::string& error_message) {
-  WebSpeechSynthesisUtterance utterance = FindUtterance(utterance_id);
-  if (utterance.IsNull())
-    return;
-
-  // The web speech API doesn't support an error message.
-  synthesizer_client_->SpeakingErrorOccurred(utterance);
-  utterance_id_map_.erase(utterance_id);
-}

+ 0 - 73
chromium_src/chrome/renderer/tts_dispatcher.h

@@ -1,73 +0,0 @@
-// Copyright (c) 2013 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 CHROME_RENDERER_TTS_DISPATCHER_H_
-#define CHROME_RENDERER_TTS_DISPATCHER_H_
-
-#include <vector>
-
-#include "base/containers/hash_tables.h"
-#include "content/public/renderer/render_thread_observer.h"
-#include "third_party/blink/public/platform/web_speech_synthesizer.h"
-#include "third_party/blink/public/platform/web_speech_synthesizer_client.h"
-
-namespace IPC {
-class Message;
-}
-
-struct TtsVoice;
-
-// TtsDispatcher is a delegate for methods used by Blink for speech synthesis
-// APIs. It's the complement of TtsDispatcherHost (owned by RenderViewHost).
-// Each TtsDispatcher is owned by the WebSpeechSynthesizerClient in Blink;
-// it registers itself to listen to IPC upon construction and unregisters
-// itself when deleted. There can be multiple TtsDispatchers alive at once,
-// so each one routes IPC messages to its WebSpeechSynthesizerClient only if
-// the utterance id (which is globally unique) matches.
-class TtsDispatcher : public blink::WebSpeechSynthesizer,
-                      public content::RenderThreadObserver {
- public:
-  explicit TtsDispatcher(blink::WebSpeechSynthesizerClient* client);
-  ~TtsDispatcher() override;
-
- private:
-  // RenderProcessObserver override.
-  bool OnControlMessageReceived(const IPC::Message& message) override;
-
-  // blink::WebSpeechSynthesizer implementation.
-  void UpdateVoiceList() override;
-  void Speak(const blink::WebSpeechSynthesisUtterance& utterance) override;
-  void Pause() override;
-  void Resume() override;
-  void Cancel() override;
-
-  blink::WebSpeechSynthesisUtterance FindUtterance(int utterance_id);
-
-  void OnSetVoiceList(const std::vector<TtsVoice>& voices);
-  void OnDidStartSpeaking(int utterance_id);
-  void OnDidFinishSpeaking(int utterance_id);
-  void OnDidPauseSpeaking(int utterance_id);
-  void OnDidResumeSpeaking(int utterance_id);
-  void OnWordBoundary(int utterance_id, int char_index);
-  void OnSentenceBoundary(int utterance_id, int char_index);
-  void OnMarkerEvent(int utterance_id, int char_index);
-  void OnWasInterrupted(int utterance_id);
-  void OnWasCancelled(int utterance_id);
-  void OnSpeakingErrorOccurred(int utterance_id,
-                               const std::string& error_message);
-
-  // The WebKit client class that we use to send events back to the JS world.
-  // Weak reference, this will be valid as long as this object exists.
-  blink::WebSpeechSynthesizerClient* synthesizer_client_;
-
-  // Next utterance id, used to map response IPCs to utterance objects.
-  static int next_utterance_id_;
-
-  // Map from id to utterance objects.
-  base::hash_map<int, blink::WebSpeechSynthesisUtterance> utterance_id_map_;
-
-  DISALLOW_COPY_AND_ASSIGN(TtsDispatcher);
-};
-
-#endif  // CHROME_RENDERER_TTS_DISPATCHER_H_

+ 0 - 52
chromium_src/library_loaders/libspeechd.h

@@ -1,52 +0,0 @@
-// This is generated file. Do not modify directly.
-// Path to the code generator:
-// tools/generate_library_loader/generate_library_loader.py .
-
-#ifndef LIBRARY_LOADER_OUT_RELEASE_GEN_LIBRARY_LOADERS_LIBSPEECHD_H
-#define LIBRARY_LOADER_OUT_RELEASE_GEN_LIBRARY_LOADERS_LIBSPEECHD_H
-
-#include "third_party/speech-dispatcher/libspeechd.h"
-#define LIBRARY_LOADER_OUT_RELEASE_GEN_LIBRARY_LOADERS_LIBSPEECHD_H_DLOPEN
-
-#include <string>
-
-class LibSpeechdLoader {
- public:
-  LibSpeechdLoader();
-  ~LibSpeechdLoader();
-
-  bool Load(const std::string& library_name)
-      __attribute__((warn_unused_result));
-
-  bool loaded() const { return loaded_; }
-
-  decltype(&::spd_open) spd_open;
-  decltype(&::spd_say) spd_say;
-  decltype(&::spd_stop) spd_stop;
-  decltype(&::spd_close) spd_close;
-  decltype(&::spd_pause) spd_pause;
-  decltype(&::spd_resume) spd_resume;
-  decltype(&::spd_set_notification_on) spd_set_notification_on;
-  decltype(&::spd_set_voice_rate) spd_set_voice_rate;
-  decltype(&::spd_set_voice_pitch) spd_set_voice_pitch;
-  decltype(&::spd_list_synthesis_voices) spd_list_synthesis_voices;
-  decltype(&::spd_set_synthesis_voice) spd_set_synthesis_voice;
-  decltype(&::spd_list_modules) spd_list_modules;
-  decltype(&::spd_set_output_module) spd_set_output_module;
-  decltype(&::spd_set_language) spd_set_language;
-
- private:
-  void CleanUp(bool unload);
-
-#if defined(LIBRARY_LOADER_OUT_RELEASE_GEN_LIBRARY_LOADERS_LIBSPEECHD_H_DLOPEN)
-  void* library_;
-#endif
-
-  bool loaded_;
-
-  // Disallow copy constructor and assignment operator.
-  LibSpeechdLoader(const LibSpeechdLoader&);
-  void operator=(const LibSpeechdLoader&);
-};
-
-#endif  // LIBRARY_LOADER_OUT_RELEASE_GEN_LIBRARY_LOADERS_LIBSPEECHD_H

+ 0 - 252
chromium_src/library_loaders/libspeechd_loader.cc

@@ -1,252 +0,0 @@
-// This is generated file. Do not modify directly.
-// Path to the code generator:
-// tools/generate_library_loader/generate_library_loader.py .
-
-#include "library_loaders/libspeechd.h"
-
-#include <dlfcn.h>
-
-// Put these sanity checks here so that they fire at most once
-// (to avoid cluttering the build output).
-#if !defined(                                                              \
-    LIBRARY_LOADER_OUT_RELEASE_GEN_LIBRARY_LOADERS_LIBSPEECHD_H_DLOPEN) && \
-    !defined(                                                              \
-        LIBRARY_LOADER_OUT_RELEASE_GEN_LIBRARY_LOADERS_LIBSPEECHD_H_DT_NEEDED)
-#error neither LIBRARY_LOADER_OUT_RELEASE_GEN_LIBRARY_LOADERS_LIBSPEECHD_H_DLOPEN nor LIBRARY_LOADER_OUT_RELEASE_GEN_LIBRARY_LOADERS_LIBSPEECHD_H_DT_NEEDED defined
-#endif
-#if defined(                                                               \
-    LIBRARY_LOADER_OUT_RELEASE_GEN_LIBRARY_LOADERS_LIBSPEECHD_H_DLOPEN) && \
-    defined(                                                               \
-        LIBRARY_LOADER_OUT_RELEASE_GEN_LIBRARY_LOADERS_LIBSPEECHD_H_DT_NEEDED)
-#error both LIBRARY_LOADER_OUT_RELEASE_GEN_LIBRARY_LOADERS_LIBSPEECHD_H_DLOPEN and LIBRARY_LOADER_OUT_RELEASE_GEN_LIBRARY_LOADERS_LIBSPEECHD_H_DT_NEEDED defined
-#endif
-
-LibSpeechdLoader::LibSpeechdLoader() : loaded_(false) {}
-
-LibSpeechdLoader::~LibSpeechdLoader() {
-  CleanUp(loaded_);
-}
-
-bool LibSpeechdLoader::Load(const std::string& library_name) {
-  if (loaded_)
-    return false;
-
-#if defined(LIBRARY_LOADER_OUT_RELEASE_GEN_LIBRARY_LOADERS_LIBSPEECHD_H_DLOPEN)
-  library_ = dlopen(library_name.c_str(), RTLD_LAZY);
-  if (!library_)
-    return false;
-#endif
-
-#if defined(LIBRARY_LOADER_OUT_RELEASE_GEN_LIBRARY_LOADERS_LIBSPEECHD_H_DLOPEN)
-  spd_open =
-      reinterpret_cast<decltype(this->spd_open)>(dlsym(library_, "spd_open"));
-#endif
-#if defined( \
-    LIBRARY_LOADER_OUT_RELEASE_GEN_LIBRARY_LOADERS_LIBSPEECHD_H_DT_NEEDED)
-  spd_open = &::spd_open;
-#endif
-  if (!spd_open) {
-    CleanUp(true);
-    return false;
-  }
-
-#if defined(LIBRARY_LOADER_OUT_RELEASE_GEN_LIBRARY_LOADERS_LIBSPEECHD_H_DLOPEN)
-  spd_say =
-      reinterpret_cast<decltype(this->spd_say)>(dlsym(library_, "spd_say"));
-#endif
-#if defined( \
-    LIBRARY_LOADER_OUT_RELEASE_GEN_LIBRARY_LOADERS_LIBSPEECHD_H_DT_NEEDED)
-  spd_say = &::spd_say;
-#endif
-  if (!spd_say) {
-    CleanUp(true);
-    return false;
-  }
-
-#if defined(LIBRARY_LOADER_OUT_RELEASE_GEN_LIBRARY_LOADERS_LIBSPEECHD_H_DLOPEN)
-  spd_stop =
-      reinterpret_cast<decltype(this->spd_stop)>(dlsym(library_, "spd_stop"));
-#endif
-#if defined( \
-    LIBRARY_LOADER_OUT_RELEASE_GEN_LIBRARY_LOADERS_LIBSPEECHD_H_DT_NEEDED)
-  spd_stop = &::spd_stop;
-#endif
-  if (!spd_stop) {
-    CleanUp(true);
-    return false;
-  }
-
-#if defined(LIBRARY_LOADER_OUT_RELEASE_GEN_LIBRARY_LOADERS_LIBSPEECHD_H_DLOPEN)
-  spd_close =
-      reinterpret_cast<decltype(this->spd_close)>(dlsym(library_, "spd_close"));
-#endif
-#if defined( \
-    LIBRARY_LOADER_OUT_RELEASE_GEN_LIBRARY_LOADERS_LIBSPEECHD_H_DT_NEEDED)
-  spd_close = &::spd_close;
-#endif
-  if (!spd_close) {
-    CleanUp(true);
-    return false;
-  }
-
-#if defined(LIBRARY_LOADER_OUT_RELEASE_GEN_LIBRARY_LOADERS_LIBSPEECHD_H_DLOPEN)
-  spd_pause =
-      reinterpret_cast<decltype(this->spd_pause)>(dlsym(library_, "spd_pause"));
-#endif
-#if defined( \
-    LIBRARY_LOADER_OUT_RELEASE_GEN_LIBRARY_LOADERS_LIBSPEECHD_H_DT_NEEDED)
-  spd_pause = &::spd_pause;
-#endif
-  if (!spd_pause) {
-    CleanUp(true);
-    return false;
-  }
-
-#if defined(LIBRARY_LOADER_OUT_RELEASE_GEN_LIBRARY_LOADERS_LIBSPEECHD_H_DLOPEN)
-  spd_resume = reinterpret_cast<decltype(this->spd_resume)>(
-      dlsym(library_, "spd_resume"));
-#endif
-#if defined( \
-    LIBRARY_LOADER_OUT_RELEASE_GEN_LIBRARY_LOADERS_LIBSPEECHD_H_DT_NEEDED)
-  spd_resume = &::spd_resume;
-#endif
-  if (!spd_resume) {
-    CleanUp(true);
-    return false;
-  }
-
-#if defined(LIBRARY_LOADER_OUT_RELEASE_GEN_LIBRARY_LOADERS_LIBSPEECHD_H_DLOPEN)
-  spd_set_notification_on =
-      reinterpret_cast<decltype(this->spd_set_notification_on)>(
-          dlsym(library_, "spd_set_notification_on"));
-#endif
-#if defined( \
-    LIBRARY_LOADER_OUT_RELEASE_GEN_LIBRARY_LOADERS_LIBSPEECHD_H_DT_NEEDED)
-  spd_set_notification_on = &::spd_set_notification_on;
-#endif
-  if (!spd_set_notification_on) {
-    CleanUp(true);
-    return false;
-  }
-
-#if defined(LIBRARY_LOADER_OUT_RELEASE_GEN_LIBRARY_LOADERS_LIBSPEECHD_H_DLOPEN)
-  spd_set_voice_rate = reinterpret_cast<decltype(this->spd_set_voice_rate)>(
-      dlsym(library_, "spd_set_voice_rate"));
-#endif
-#if defined( \
-    LIBRARY_LOADER_OUT_RELEASE_GEN_LIBRARY_LOADERS_LIBSPEECHD_H_DT_NEEDED)
-  spd_set_voice_rate = &::spd_set_voice_rate;
-#endif
-  if (!spd_set_voice_rate) {
-    CleanUp(true);
-    return false;
-  }
-
-#if defined(LIBRARY_LOADER_OUT_RELEASE_GEN_LIBRARY_LOADERS_LIBSPEECHD_H_DLOPEN)
-  spd_set_voice_pitch = reinterpret_cast<decltype(this->spd_set_voice_pitch)>(
-      dlsym(library_, "spd_set_voice_pitch"));
-#endif
-#if defined( \
-    LIBRARY_LOADER_OUT_RELEASE_GEN_LIBRARY_LOADERS_LIBSPEECHD_H_DT_NEEDED)
-  spd_set_voice_pitch = &::spd_set_voice_pitch;
-#endif
-  if (!spd_set_voice_pitch) {
-    CleanUp(true);
-    return false;
-  }
-
-#if defined(LIBRARY_LOADER_OUT_RELEASE_GEN_LIBRARY_LOADERS_LIBSPEECHD_H_DLOPEN)
-  spd_list_synthesis_voices =
-      reinterpret_cast<decltype(this->spd_list_synthesis_voices)>(
-          dlsym(library_, "spd_list_synthesis_voices"));
-#endif
-#if defined( \
-    LIBRARY_LOADER_OUT_RELEASE_GEN_LIBRARY_LOADERS_LIBSPEECHD_H_DT_NEEDED)
-  spd_list_synthesis_voices = &::spd_list_synthesis_voices;
-#endif
-  if (!spd_list_synthesis_voices) {
-    CleanUp(true);
-    return false;
-  }
-
-#if defined(LIBRARY_LOADER_OUT_RELEASE_GEN_LIBRARY_LOADERS_LIBSPEECHD_H_DLOPEN)
-  spd_set_synthesis_voice =
-      reinterpret_cast<decltype(this->spd_set_synthesis_voice)>(
-          dlsym(library_, "spd_set_synthesis_voice"));
-#endif
-#if defined( \
-    LIBRARY_LOADER_OUT_RELEASE_GEN_LIBRARY_LOADERS_LIBSPEECHD_H_DT_NEEDED)
-  spd_set_synthesis_voice = &::spd_set_synthesis_voice;
-#endif
-  if (!spd_set_synthesis_voice) {
-    CleanUp(true);
-    return false;
-  }
-
-#if defined(LIBRARY_LOADER_OUT_RELEASE_GEN_LIBRARY_LOADERS_LIBSPEECHD_H_DLOPEN)
-  spd_list_modules = reinterpret_cast<decltype(this->spd_list_modules)>(
-      dlsym(library_, "spd_list_modules"));
-#endif
-#if defined( \
-    LIBRARY_LOADER_OUT_RELEASE_GEN_LIBRARY_LOADERS_LIBSPEECHD_H_DT_NEEDED)
-  spd_list_modules = &::spd_list_modules;
-#endif
-  if (!spd_list_modules) {
-    CleanUp(true);
-    return false;
-  }
-
-#if defined(LIBRARY_LOADER_OUT_RELEASE_GEN_LIBRARY_LOADERS_LIBSPEECHD_H_DLOPEN)
-  spd_set_output_module =
-      reinterpret_cast<decltype(this->spd_set_output_module)>(
-          dlsym(library_, "spd_set_output_module"));
-#endif
-#if defined( \
-    LIBRARY_LOADER_OUT_RELEASE_GEN_LIBRARY_LOADERS_LIBSPEECHD_H_DT_NEEDED)
-  spd_set_output_module = &::spd_set_output_module;
-#endif
-  if (!spd_set_output_module) {
-    CleanUp(true);
-    return false;
-  }
-
-#if defined(LIBRARY_LOADER_OUT_RELEASE_GEN_LIBRARY_LOADERS_LIBSPEECHD_H_DLOPEN)
-  spd_set_language = reinterpret_cast<decltype(this->spd_set_language)>(
-      dlsym(library_, "spd_set_language"));
-#endif
-#if defined( \
-    LIBRARY_LOADER_OUT_RELEASE_GEN_LIBRARY_LOADERS_LIBSPEECHD_H_DT_NEEDED)
-  spd_set_language = &::spd_set_language;
-#endif
-  if (!spd_set_language) {
-    CleanUp(true);
-    return false;
-  }
-
-  loaded_ = true;
-  return true;
-}
-
-void LibSpeechdLoader::CleanUp(bool unload) {
-#if defined(LIBRARY_LOADER_OUT_RELEASE_GEN_LIBRARY_LOADERS_LIBSPEECHD_H_DLOPEN)
-  if (unload) {
-    dlclose(library_);
-    library_ = NULL;
-  }
-#endif
-  loaded_ = false;
-  spd_open = NULL;
-  spd_say = NULL;
-  spd_stop = NULL;
-  spd_close = NULL;
-  spd_pause = NULL;
-  spd_resume = NULL;
-  spd_set_notification_on = NULL;
-  spd_set_voice_rate = NULL;
-  spd_set_voice_pitch = NULL;
-  spd_list_synthesis_voices = NULL;
-  spd_set_synthesis_voice = NULL;
-  spd_list_modules = NULL;
-  spd_set_output_module = NULL;
-  spd_set_language = NULL;
-}

+ 2 - 19
filenames.gni

@@ -577,8 +577,8 @@ filenames = {
     "atom/renderer/web_worker_observer.h",
     "atom/utility/atom_content_utility_client.cc",
     "atom/utility/atom_content_utility_client.h",
-    "chromium_src/chrome/browser/browser_process.cc",
-    "chromium_src/chrome/browser/browser_process.h",
+    "chromium_src/chrome/browser/browser_process_impl.cc",
+    "chromium_src/chrome/browser/browser_process_impl.h",
     "chromium_src/chrome/browser/chrome_process_finder_win.cc",
     "chromium_src/chrome/browser/chrome_process_finder_win.h",
     "chromium_src/chrome/browser/chrome_notification_types.h",
@@ -604,16 +604,6 @@ filenames = {
     "chromium_src/chrome/browser/process_singleton_posix.cc",
     "chromium_src/chrome/browser/process_singleton_win.cc",
     "chromium_src/chrome/browser/process_singleton.h",
-    "chromium_src/chrome/browser/speech/tts_controller.h",
-    "chromium_src/chrome/browser/speech/tts_controller_impl.cc",
-    "chromium_src/chrome/browser/speech/tts_controller_impl.h",
-    "chromium_src/chrome/browser/speech/tts_linux.cc",
-    "chromium_src/chrome/browser/speech/tts_mac.mm",
-    "chromium_src/chrome/browser/speech/tts_message_filter.cc",
-    "chromium_src/chrome/browser/speech/tts_message_filter.h",
-    "chromium_src/chrome/browser/speech/tts_platform.cc",
-    "chromium_src/chrome/browser/speech/tts_platform.h",
-    "chromium_src/chrome/browser/speech/tts_win.cc",
     "chromium_src/chrome/browser/ui/browser_dialogs.h",
     "chromium_src/chrome/browser/ui/cocoa/color_chooser_mac.mm",
     "chromium_src/chrome/browser/ui/views/color_chooser_aura.cc",
@@ -622,9 +612,6 @@ filenames = {
     "chromium_src/chrome/browser/ui/views/frame/global_menu_bar_registrar_x11.h",
     "chromium_src/chrome/common/print_messages.cc",
     "chromium_src/chrome/common/print_messages.h",
-    "chromium_src/chrome/common/tts_messages.h",
-    "chromium_src/chrome/common/tts_utterance_request.cc",
-    "chromium_src/chrome/common/tts_utterance_request.h",
     "chromium_src/chrome/renderer/printing/print_web_view_helper.cc",
     "chromium_src/chrome/renderer/printing/print_web_view_helper_linux.cc",
     "chromium_src/chrome/renderer/printing/print_web_view_helper_mac.mm",
@@ -632,11 +619,7 @@ filenames = {
     "chromium_src/chrome/renderer/printing/print_web_view_helper.h",
     "chromium_src/chrome/renderer/spellchecker/spellcheck_worditerator.cc",
     "chromium_src/chrome/renderer/spellchecker/spellcheck_worditerator.h",
-    "chromium_src/chrome/renderer/tts_dispatcher.cc",
-    "chromium_src/chrome/renderer/tts_dispatcher.h",
     "chromium_src/chrome/utility/utility_message_handler.h",
-    "chromium_src/library_loaders/libspeechd_loader.cc",
-    "chromium_src/library_loaders/libspeechd.h",
   ]
 
   lib_sources_nss = [

+ 10 - 6
patches/common/chromium/.patches.yaml

@@ -380,7 +380,7 @@ patches:
   file: allow_nested_error_trackers.patch
   description: |
     Only one X11ErrorTracker should exist at a time, but upstream has a bug
-    where two can exist if running in headless mode -- 
+    where two can exist if running in headless mode --
       ui::(anonymous namespace)::SupportsEWMH() [inner tracker is created]
       ui::WmSupportsHint()
       ui::IsX11WindowFullScreen()
@@ -430,11 +430,6 @@ patches:
   description: |
     Compilation of those files fails with the Chromium 68.
     Remove the patch during the Chromium 69 upgrade.
--
-  author: deepak1556 <[email protected]>
-  file: disable_extensions_gn.patch
-  description: |
-    Fix build files generation when chrome extensions are disabled.
 -
   author: Jeremy Apthorp <[email protected]>
   file: crashpad_http_status.patch
@@ -503,3 +498,12 @@ patches:
     (and aren't compiling command.cc), it's safe to duplicate the
     definition. A candidate for upstreaming would be to move the IsMediaKey
     function into //ui.
+-
+  author: Heilig Benedek <[email protected]>
+  file: tts.patch
+  description:  |
+    * Adds patch in //chrome/browser/speech/tts_controller_impl.cc
+      to disable calls using chrome profile class.
+    * Adds patch in //chrome/browser/speech/tts_message_filter.cc
+      to remove reference to browser context when its signaled for
+      destruction from content layer.

+ 0 - 65
patches/common/chromium/disable_extensions_gn.patch

@@ -1,65 +0,0 @@
-From 790e1e19af133252e95e3a4de8c8e7a3a011bf02 Mon Sep 17 00:00:00 2001
-From: deepak1556 <[email protected]>
-Date: Thu, 20 Sep 2018 17:50:48 -0700
-Subject: disable_extensions_gn.patch
-
-Fix build files generation when chrome extensions are disabled.
-
-diff --git a/chrome/browser/apps/app_shim/BUILD.gn b/chrome/browser/apps/app_shim/BUILD.gn
-index f8a6d1868788..350c3572ec54 100644
---- a/chrome/browser/apps/app_shim/BUILD.gn
-+++ b/chrome/browser/apps/app_shim/BUILD.gn
-@@ -1,6 +1,7 @@
- # Copyright 2015 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.
-+import("//extensions/buildflags/buildflags.gni")
- 
- # This is the part of the Chrome browser process responsible for launching and
- # communicating with app_shim processes on Mac.
-@@ -14,8 +15,6 @@ source_set("app_shim") {
-     "app_shim_host_manager_mac.mm",
-     "apps_page_shim_handler.h",
-     "apps_page_shim_handler.mm",
--    "extension_app_shim_handler_mac.cc",
--    "extension_app_shim_handler_mac.h",
-     "unix_domain_socket_acceptor.cc",
-     "unix_domain_socket_acceptor.h",
-   ]
-@@ -24,7 +23,16 @@ source_set("app_shim") {
-     "//chrome/common:mojo_bindings",
-     "//content/public/browser",
-     "//content/public/common",
--    "//extensions/browser",
--    "//extensions/common",
-   ]
-+
-+  if (enable_extensions) {
-+    sources += [
-+      "extension_app_shim_handler_mac.cc",
-+      "extension_app_shim_handler_mac.h",
-+    ]
-+    deps += [
-+      "//extensions/browser",
-+      "//extensions/common",
-+    ]
-+  }
- }
-diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn
-index 1b14d628a63b..00401612c191 100644
---- a/chrome/browser/ui/BUILD.gn
-+++ b/chrome/browser/ui/BUILD.gn
-@@ -2570,7 +2570,10 @@ split_static_library("ui") {
-         "views/tabs/window_finder_mac.mm",
-       ]
- 
--      deps += [ "//extensions/components/native_app_window" ]
-+
-+      if (enable_extensions) {
-+        deps += [ "//extensions/components/native_app_window" ]
-+      }
- 
-       # Truly cocoa-browser-specific sources. These are secondary UI pieces that
-       # are obsolete before mac_views_browser will ever ship, so they aren't
--- 
-2.17.0

+ 164 - 0
patches/common/chromium/tts.patch

@@ -0,0 +1,164 @@
+diff --git a/chrome/browser/speech/tts_controller_impl.cc b/chrome/browser/speech/tts_controller_impl.cc
+index 2ca56c3a247e..f58e33b3c019 100644
+--- a/chrome/browser/speech/tts_controller_impl.cc
++++ b/chrome/browser/speech/tts_controller_impl.cc
+@@ -624,12 +624,14 @@ const PrefService* TtsControllerImpl::GetPrefService(
+     const Utterance* utterance) {
+   const PrefService* prefs = nullptr;
+   // The utterance->browser_context() is null in tests.
++#if 0
+   if (utterance->browser_context()) {
+     const Profile* profile =
+         Profile::FromBrowserContext(utterance->browser_context());
+     if (profile)
+       prefs = profile->GetPrefs();
+   }
++#endif
+   return prefs;
+ }
+ 
+diff --git a/chrome/browser/speech/tts_message_filter.cc b/chrome/browser/speech/tts_message_filter.cc
+index 013c7a9c60f9..73a244a726e3 100644
+--- a/chrome/browser/speech/tts_message_filter.cc
++++ b/chrome/browser/speech/tts_message_filter.cc
+@@ -9,14 +9,40 @@
+ #include "base/bind.h"
+ #include "base/logging.h"
+ #include "chrome/browser/chrome_notification_types.h"
++#if 0
+ #include "chrome/browser/profiles/profile.h"
++#endif
+ #include "chrome/common/tts_messages.h"
++#include "components/keyed_service/content/browser_context_keyed_service_shutdown_notifier_factory.h"
+ #include "content/public/browser/browser_context.h"
+ #include "content/public/browser/notification_service.h"
+ #include "content/public/browser/render_process_host.h"
+ 
+ using content::BrowserThread;
+ 
++namespace {
++
++class TtsMessageFilterShutdownNotifierFactory
++    : public BrowserContextKeyedServiceShutdownNotifierFactory {
++ public:
++  static TtsMessageFilterShutdownNotifierFactory* GetInstance() {
++    return base::Singleton<TtsMessageFilterShutdownNotifierFactory>::get();
++  }
++
++ private:
++  friend struct base::DefaultSingletonTraits<
++      TtsMessageFilterShutdownNotifierFactory>;
++
++  TtsMessageFilterShutdownNotifierFactory()
++      : BrowserContextKeyedServiceShutdownNotifierFactory("TtsMessageFilter") {}
++
++  ~TtsMessageFilterShutdownNotifierFactory() override {}
++
++  DISALLOW_COPY_AND_ASSIGN(TtsMessageFilterShutdownNotifierFactory);
++};
++
++}  // namespace
++
+ TtsMessageFilter::TtsMessageFilter(content::BrowserContext* browser_context)
+     : BrowserMessageFilter(TtsMsgStart),
+       browser_context_(browser_context),
+@@ -24,28 +50,27 @@ TtsMessageFilter::TtsMessageFilter(content::BrowserContext* browser_context)
+   CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+   TtsController::GetInstance()->AddVoicesChangedDelegate(this);
+ 
+-  // TODO(dmazzoni): make it so that we can listen for a BrowserContext
+-  // being destroyed rather than a Profile.  http://crbug.com/444668
+-  Profile* profile = Profile::FromBrowserContext(browser_context);
+-  notification_registrar_.Add(this,
+-                              chrome::NOTIFICATION_PROFILE_DESTROYED,
+-                              content::Source<Profile>(profile));
++  browser_context_shutdown_notifier_ =
++      TtsMessageFilterShutdownNotifierFactory::GetInstance()
++          ->Get(browser_context)
++          ->Subscribe(base::Bind(&TtsMessageFilter::BrowserContextDestroyed,
++                                 base::RetainedRef(this)));
+ 
+   // Balanced in OnChannelClosingInUIThread() to keep the ref-count be non-zero
+   // until all pointers to this class are invalidated.
+   AddRef();
+ }
+ 
+-void TtsMessageFilter::OverrideThreadForMessage(
+-    const IPC::Message& message, BrowserThread::ID* thread) {
++void TtsMessageFilter::OverrideThreadForMessage(const IPC::Message& message,
++                                                BrowserThread::ID* thread) {
+   switch (message.type()) {
+-  case TtsHostMsg_InitializeVoiceList::ID:
+-  case TtsHostMsg_Speak::ID:
+-  case TtsHostMsg_Pause::ID:
+-  case TtsHostMsg_Resume::ID:
+-  case TtsHostMsg_Cancel::ID:
+-    *thread = BrowserThread::UI;
+-    break;
++    case TtsHostMsg_InitializeVoiceList::ID:
++    case TtsHostMsg_Speak::ID:
++    case TtsHostMsg_Pause::ID:
++    case TtsHostMsg_Resume::ID:
++    case TtsHostMsg_Cancel::ID:
++      *thread = BrowserThread::UI;
++      break;
+   }
+ }
+ 
+@@ -207,10 +232,8 @@ void TtsMessageFilter::Cleanup() {
+   TtsController::GetInstance()->RemoveUtteranceEventDelegate(this);
+ }
+ 
+-void TtsMessageFilter::Observe(
+-    int type,
+-    const content::NotificationSource& source,
+-    const content::NotificationDetails& details) {
++void TtsMessageFilter::BrowserContextDestroyed() {
++  CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+   browser_context_ = nullptr;
+-  notification_registrar_.RemoveAll();
++  browser_context_shutdown_notifier_.reset();
+ }
+diff --git a/chrome/browser/speech/tts_message_filter.h b/chrome/browser/speech/tts_message_filter.h
+index cc9e2806b5c3..d21fb42f1aca 100644
+--- a/chrome/browser/speech/tts_message_filter.h
++++ b/chrome/browser/speech/tts_message_filter.h
+@@ -9,10 +9,9 @@
+ #include "base/memory/weak_ptr.h"
+ #include "base/synchronization/lock.h"
+ #include "chrome/browser/speech/tts_controller.h"
++#include "components/keyed_service/core/keyed_service_shutdown_notifier.h"
+ #include "content/public/browser/browser_message_filter.h"
+ #include "content/public/browser/browser_thread.h"
+-#include "content/public/browser/notification_observer.h"
+-#include "content/public/browser/notification_registrar.h"
+ 
+ namespace content {
+ class BrowserContext;
+@@ -22,7 +21,6 @@ struct TtsUtteranceRequest;
+ 
+ class TtsMessageFilter
+     : public content::BrowserMessageFilter,
+-      public content::NotificationObserver,
+       public UtteranceEventDelegate,
+       public VoicesChangedDelegate {
+  public:
+@@ -64,15 +62,13 @@ class TtsMessageFilter
+   // about to be deleted.
+   bool Valid();
+ 
+-  // content::NotificationObserver implementation.
+-  void Observe(int type,
+-               const content::NotificationSource& source,
+-               const content::NotificationDetails& details) override;
++  void BrowserContextDestroyed();
+ 
++  std::unique_ptr<KeyedServiceShutdownNotifier::Subscription>
++      browser_context_shutdown_notifier_;
+   content::BrowserContext* browser_context_;
+   mutable base::Lock mutex_;
+   mutable bool valid_;
+-  content::NotificationRegistrar notification_registrar_;
+ 
+   DISALLOW_COPY_AND_ASSIGN(TtsMessageFilter);
+ };

+ 42 - 0
spec/chromium-spec.js

@@ -1,4 +1,6 @@
 const assert = require('assert')
+const chai = require('chai')
+const dirtyChai = require('dirty-chai')
 const fs = require('fs')
 const http = require('http')
 const path = require('path')
@@ -12,6 +14,9 @@ const { app, BrowserWindow, ipcMain, protocol, session, webContents } = remote
 const isCI = remote.getGlobal('isCi')
 const features = process.atomBinding('features')
 
+const { expect } = chai
+chai.use(dirtyChai)
+
 /* Most of the APIs here don't use standard callbacks */
 /* eslint-disable standard/no-callback-literal */
 
@@ -1269,4 +1274,41 @@ describe('chromium feature', () => {
       })
     })
   })
+
+  describe('SpeechSynthesis', () => {
+    before(function () {
+      if (isCI || !features.isTtsEnabled()) {
+        this.skip()
+      }
+    })
+
+    it('should emit lifecycle events', async () => {
+      const sentence = `long sentence which will take at least a few seconds to
+          utter so that it's possible to pause and resume before the end`
+      const utter = new SpeechSynthesisUtterance(sentence)
+      // Create a dummy utterence so that speech synthesis state
+      // is initialized for later calls.
+      speechSynthesis.speak(new SpeechSynthesisUtterance())
+      speechSynthesis.cancel()
+      speechSynthesis.speak(utter)
+      // paused state after speak()
+      expect(speechSynthesis.paused).to.be.false()
+      await new Promise((resolve) => { utter.onstart = resolve })
+      // paused state after start event
+      expect(speechSynthesis.paused).to.be.false()
+
+      speechSynthesis.pause()
+      // paused state changes async, right before the pause event
+      expect(speechSynthesis.paused).to.be.false()
+      await new Promise((resolve) => { utter.onpause = resolve })
+      expect(speechSynthesis.paused).to.be.true()
+
+      speechSynthesis.resume()
+      await new Promise((resolve) => { utter.onresume = resolve })
+      // paused state after resume event
+      expect(speechSynthesis.paused).to.be.false()
+
+      await new Promise((resolve) => { utter.onend = resolve })
+    })
+  })
 })