summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/extensions/extension_function_dispatcher.cc10
-rw-r--r--chrome/browser/extensions/extension_tts_api.cc50
-rw-r--r--chrome/browser/extensions/extension_tts_api.h29
-rw-r--r--chrome/browser/extensions/extension_tts_apitest.cc26
-rw-r--r--chrome/chrome_browser.gypi4
-rw-r--r--chrome/chrome_tests.gypi5
-rw-r--r--chrome/common/extensions/api/extension_api.json90
-rw-r--r--chrome/renderer/resources/extension_apitest.js14
-rw-r--r--chrome/renderer/resources/extension_process_bindings.js3
-rw-r--r--chrome/renderer/resources/renderer_extension_bindings.js1
-rw-r--r--chrome/test/data/extensions/api_test/tts/manifest.json7
-rw-r--r--chrome/test/data/extensions/api_test/tts/test.html1
-rw-r--r--chrome/test/data/extensions/api_test/tts/test.js31
13 files changed, 270 insertions, 1 deletions
diff --git a/chrome/browser/extensions/extension_function_dispatcher.cc b/chrome/browser/extensions/extension_function_dispatcher.cc
index b27d65ee..8371346 100644
--- a/chrome/browser/extensions/extension_function_dispatcher.cc
+++ b/chrome/browser/extensions/extension_function_dispatcher.cc
@@ -45,6 +45,9 @@
#include "chrome/browser/extensions/extension_tabs_module_constants.h"
#include "chrome/browser/extensions/extension_test_api.h"
#include "chrome/browser/extensions/extension_toolstrip_api.h"
+#if defined(OS_CHROMEOS)
+#include "chrome/browser/extensions/extension_tts_api.h"
+#endif
#include "chrome/browser/extensions/extensions_quota_service.h"
#include "chrome/browser/extensions/extensions_service.h"
#include "chrome/browser/profile.h"
@@ -231,6 +234,13 @@ void FactoryRegistry::ResetFunctions() {
RegisterFunction<GetFocusedControlFunction>();
RegisterFunction<SetAccessibilityEnabledFunction>();
+#if defined(OS_CHROMEOS)
+ // Text-to-speech.
+ RegisterFunction<ExtensionTtsSpeakFunction>();
+ RegisterFunction<ExtensionTtsStopSpeakingFunction>();
+ RegisterFunction<ExtensionTtsIsSpeakingFunction>();
+#endif
+
// Clipboard.
RegisterFunction<ExecuteCopyClipboardFunction>();
RegisterFunction<ExecuteCutClipboardFunction>();
diff --git a/chrome/browser/extensions/extension_tts_api.cc b/chrome/browser/extensions/extension_tts_api.cc
new file mode 100644
index 0000000..1cfdd43
--- /dev/null
+++ b/chrome/browser/extensions/extension_tts_api.cc
@@ -0,0 +1,50 @@
+// Copyright (c) 2009 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/extensions/extension_tts_api.h"
+
+#include <string>
+
+#include "base/values.h"
+
+#include "chrome/browser/chromeos/cros/cros_library.h"
+#include "chrome/browser/chromeos/cros/speech_synthesis_library.h"
+
+namespace {
+ const char kCrosLibraryNotLoadedError[] =
+ "Cros shared library not loaded.";
+};
+
+bool ExtensionTtsSpeakFunction::RunImpl() {
+ std::string utterance;
+ EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &utterance));
+ if (chromeos::CrosLibrary::Get()->EnsureLoaded()) {
+ bool ret = chromeos::CrosLibrary::Get()->GetSpeechSynthesisLibrary()->
+ Speak(utterance.c_str());
+ result_.reset();
+ return ret;
+ }
+ error_ = kCrosLibraryNotLoadedError;
+ return false;
+}
+
+bool ExtensionTtsStopSpeakingFunction::RunImpl() {
+ if (chromeos::CrosLibrary::Get()->EnsureLoaded()) {
+ return chromeos::CrosLibrary::Get()->GetSpeechSynthesisLibrary()->
+ StopSpeaking();
+ }
+ error_ = kCrosLibraryNotLoadedError;
+ return false;
+}
+
+bool ExtensionTtsIsSpeakingFunction::RunImpl() {
+ if (chromeos::CrosLibrary::Get()->EnsureLoaded()) {
+ result_.reset(Value::CreateBooleanValue(
+ chromeos::CrosLibrary::Get()->GetSpeechSynthesisLibrary()->
+ IsSpeaking()));
+ return true;
+ }
+ error_ = kCrosLibraryNotLoadedError;
+ return false;
+}
diff --git a/chrome/browser/extensions/extension_tts_api.h b/chrome/browser/extensions/extension_tts_api.h
new file mode 100644
index 0000000..d5f578d
--- /dev/null
+++ b/chrome/browser/extensions/extension_tts_api.h
@@ -0,0 +1,29 @@
+// Copyright (c) 2010 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_EXTENSIONS_EXTENSION_TTS_API_H_
+#define CHROME_BROWSER_EXTENSIONS_EXTENSION_TTS_API_H_
+
+#include "base/singleton.h"
+#include "chrome/browser/extensions/extension_function.h"
+
+class ExtensionTtsSpeakFunction : public SyncExtensionFunction {
+ ~ExtensionTtsSpeakFunction() {}
+ virtual bool RunImpl();
+ DECLARE_EXTENSION_FUNCTION_NAME("experimental.tts.speak")
+};
+
+class ExtensionTtsStopSpeakingFunction : public SyncExtensionFunction {
+ ~ExtensionTtsStopSpeakingFunction() {}
+ virtual bool RunImpl();
+ DECLARE_EXTENSION_FUNCTION_NAME("experimental.tts.stop")
+};
+
+class ExtensionTtsIsSpeakingFunction : public SyncExtensionFunction {
+ ~ExtensionTtsIsSpeakingFunction() {}
+ virtual bool RunImpl();
+ DECLARE_EXTENSION_FUNCTION_NAME("experimental.tts.isSpeaking")
+};
+
+#endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_TTS_API_H_
diff --git a/chrome/browser/extensions/extension_tts_apitest.cc b/chrome/browser/extensions/extension_tts_apitest.cc
new file mode 100644
index 0000000..5acda10
--- /dev/null
+++ b/chrome/browser/extensions/extension_tts_apitest.cc
@@ -0,0 +1,26 @@
+// Copyright (c) 2010 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 "base/command_line.h"
+#include "chrome/browser/chromeos/cros/cros_mock.h"
+#include "chrome/browser/extensions/extension_apitest.h"
+#include "chrome/common/chrome_switches.h"
+#include "testing/gmock/include/gmock/gmock.h"
+
+// This extension API is currently only supported on Chrome OS.
+#if defined(OS_CHROMEOS)
+#define MAYBE_Tts Tts
+#else
+#define MAYBE_Tts DISABLED_Tts
+#endif
+
+IN_PROC_BROWSER_TEST_F(ExtensionApiTest, MAYBE_Tts) {
+ CommandLine::ForCurrentProcess()->AppendSwitch(
+ switches::kEnableExperimentalExtensionApis);
+
+ chromeos::CrosMock crosMock;
+ crosMock.InitMockSpeechSynthesisLibrary();
+ crosMock.SetSpeechSynthesisLibraryExpectations();
+
+ ASSERT_TRUE(RunExtensionTest("tts")) << message_;
+}
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index 5ab036e..6ff3ee1 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -1382,6 +1382,8 @@
'browser/extensions/extension_tabs_module_constants.h',
'browser/extensions/extension_test_api.cc',
'browser/extensions/extension_test_api.h',
+ 'browser/extensions/extension_tts_api.cc',
+ 'browser/extensions/extension_tts_api.h',
'browser/extensions/extension_toolbar_model.cc',
'browser/extensions/extension_toolbar_model.h',
'browser/extensions/extension_toolstrip_api.cc',
@@ -2971,6 +2973,8 @@
['exclude', 'browser/dom_ui/filebrowse_ui.cc'],
['exclude', 'browser/dom_ui/mediaplayer_ui.cc'],
['exclude', 'browser/dom_ui/slideshow_ui.cc'],
+ ['exclude', 'browser/extensions/extension_tts_api.cc'],
+ ['exclude', 'browser/extensions/extension_tts_api.h'],
['exclude', 'browser/renderer_host/offline_resource_handler.cc'],
['exclude', 'browser/renderer_host/offline_resource_handler.h'],
],
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi
index b8f2142..4e3ff33 100644
--- a/chrome/chrome_tests.gypi
+++ b/chrome/chrome_tests.gypi
@@ -1604,6 +1604,7 @@
'browser/extensions/extension_test_message_listener.h',
'browser/extensions/extension_toolbar_model_browsertest.cc',
'browser/extensions/extension_toolstrip_apitest.cc',
+ 'browser/extensions/extension_tts_apitest.cc',
'browser/extensions/extension_webnavigation_apitest.cc',
'browser/extensions/extension_webrequest_apitest.cc',
'browser/extensions/extension_websocket_apitest.cc',
@@ -1646,6 +1647,10 @@
['chromeos==0', {
'sources/': [
['exclude', '^browser/chromeos'],
+ # Currently TTS extension API is supported only for chromeos.
+ # Remove the following exclude when support for other platforms
+ # is added.
+ ['exclude', 'browser/extensions/extension_tts_apitest.cc'],
],
'sources!': [
'browser/dom_ui/mediaplayer_browsertest.cc',
diff --git a/chrome/common/extensions/api/extension_api.json b/chrome/common/extensions/api/extension_api.json
index ea9252d..e0530b9 100644
--- a/chrome/common/extensions/api/extension_api.json
+++ b/chrome/common/extensions/api/extension_api.json
@@ -484,6 +484,96 @@
"events": []
},
{
+ "namespace": "experimental.tts",
+ "nodoc": true,
+ "functions": [
+ {
+ "name": "speak",
+ "type": "function",
+ "description": "Speak text using a text-to-speech engine.",
+ "parameters": [
+ {
+ "type": "string",
+ "name": "utterance",
+ "description": "The text to speak."
+ },
+ {
+ "type": "object",
+ "name": "options",
+ "optional": true,
+ "description": "The speak options. This parameter is currently ignored.",
+ "properties": {
+ "languageName": {
+ "type": "string",
+ "optional": true,
+ "description": "The language name for synthesis specified in the form <language>-<locale>, e.g. en-US, en-GB, fr-CA, zh-CN, etc."
+ },
+ "gender": {
+ "type": "string",
+ "optional": true,
+ "description": "Gender of voice for synthesized speech.",
+ "enum": ["male", "female"]
+ },
+ "rate": {
+ "type": "float",
+ "optional": true,
+ "minimum": 0,
+ "maximum": 1,
+ "description": "Speaking speed between 0 and 1 inclusive, with 0 being slowest and 1 being fastest."
+ },
+ "pitch": {
+ "type": "float",
+ "optional": true,
+ "minimum": 0,
+ "maximum": 1,
+ "description": "Speaking pitch between 0 and 1 inclusive, with 0 being lowest and 1 being highest."
+ },
+ "volume": {
+ "type": "float",
+ "optional": true,
+ "minimum": 0,
+ "maximum": 1,
+ "description": "Speaking volume between 0 and 1 inclusive, with 0 being lowest and 1 being highest."
+ }
+ }
+ },
+ {
+ "type": "function",
+ "name": "callback",
+ "optional": true,
+ "description": "This function is called when speaking is finished.",
+ "parameters": []
+ }
+ ]
+ },
+ {
+ "name": "stop",
+ "type": "function",
+ "description": "Stop any current speech.",
+ "parameters": []
+ },
+ {
+ "name": "isSpeaking",
+ "type": "function",
+ "description": "Check if the engine is currently speaking.",
+ "parameters": [
+ {
+ "type": "function",
+ "name": "callback",
+ "optional": true,
+ "parameters": [
+ {
+ "name": "speaking",
+ "type": "boolean",
+ "description": "True if speaking, false otherwise."
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ {
"namespace": "windows",
"types": [
{
diff --git a/chrome/renderer/resources/extension_apitest.js b/chrome/renderer/resources/extension_apitest.js
index 62c5ab9..ca7a4df 100644
--- a/chrome/renderer/resources/extension_apitest.js
+++ b/chrome/renderer/resources/extension_apitest.js
@@ -1,3 +1,7 @@
+// Copyright (c) 2010 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.
+
// extension_apitest.js
// mini-framework for ExtensionApiTest browser tests
@@ -98,7 +102,15 @@ var chrome = chrome || {};
};
chrome.test.assertTrue = function(test, message) {
- if (test !== true) {
+ chrome.test.assertBool(test, true, message);
+ };
+
+ chrome.test.assertFalse = function(test, message) {
+ chrome.test.assertBool(test, false, message);
+ };
+
+ chrome.test.assertBool = function(test, expected, message) {
+ if (test !== expected) {
if (typeof(test) == "string") {
if (message) {
message = test + "\n" + message;
diff --git a/chrome/renderer/resources/extension_process_bindings.js b/chrome/renderer/resources/extension_process_bindings.js
index 7594595..f0986f2 100644
--- a/chrome/renderer/resources/extension_process_bindings.js
+++ b/chrome/renderer/resources/extension_process_bindings.js
@@ -707,4 +707,7 @@ var chrome = chrome || {};
if (!chrome.experimental.accessibility)
chrome.experimental.accessibility = {};
+
+ if (!chrome.experimental.tts)
+ chrome.experimental.tts = {};
})();
diff --git a/chrome/renderer/resources/renderer_extension_bindings.js b/chrome/renderer/resources/renderer_extension_bindings.js
index 8a67983..62184c6 100644
--- a/chrome/renderer/resources/renderer_extension_bindings.js
+++ b/chrome/renderer/resources/renderer_extension_bindings.js
@@ -259,6 +259,7 @@ var chrome = chrome || {};
"experimental.omnibox",
"experimental.popup",
"experimental.processes",
+ "experimental.tts",
"experimental.proxy",
"experimental.rlz",
"experimental.webNavigation",
diff --git a/chrome/test/data/extensions/api_test/tts/manifest.json b/chrome/test/data/extensions/api_test/tts/manifest.json
new file mode 100644
index 0000000..a43bc3d
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/tts/manifest.json
@@ -0,0 +1,7 @@
+{
+ "name": "chrome.experimental.tts",
+ "version": "0.1",
+ "description": "browser test for chrome.experimental.tts API",
+ "background_page": "test.html",
+ "permissions": ["experimental"]
+}
diff --git a/chrome/test/data/extensions/api_test/tts/test.html b/chrome/test/data/extensions/api_test/tts/test.html
new file mode 100644
index 0000000..46f4d74
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/tts/test.html
@@ -0,0 +1 @@
+<script src="test.js"></script>
diff --git a/chrome/test/data/extensions/api_test/tts/test.js b/chrome/test/data/extensions/api_test/tts/test.js
new file mode 100644
index 0000000..df5837b
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/tts/test.js
@@ -0,0 +1,31 @@
+// Copyright (c) 2010 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.
+
+// TTS api test for Chrome. This is currently limited to ChromeOS.
+// browser_tests.exe --gtest_filter=ExtensionApiTest.Tts
+
+chrome.test.runTests([
+ function testSpeak() {
+ chrome.experimental.tts.speak('hello world', {}, function() {
+ chrome.test.succeed();
+ });
+ },
+
+ function testStop() {
+ chrome.experimental.tts.stop();
+ chrome.test.succeed();
+ },
+
+ function testIsSpeaking() {
+ for (var i = 0; i < 3; i++) {
+ chrome.experimental.tts.isSpeaking(function(speaking) {
+ chrome.test.assertTrue(speaking);
+ });
+ }
+ chrome.experimental.tts.isSpeaking(function(speaking) {
+ chrome.test.assertFalse(speaking);
+ chrome.test.succeed();
+ });
+ }
+]); \ No newline at end of file