diff options
-rw-r--r-- | chrome/browser/extensions/extension_function_dispatcher.cc | 10 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_tts_api.cc | 50 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_tts_api.h | 29 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_tts_apitest.cc | 26 | ||||
-rw-r--r-- | chrome/chrome_browser.gypi | 4 | ||||
-rw-r--r-- | chrome/chrome_tests.gypi | 5 | ||||
-rw-r--r-- | chrome/common/extensions/api/extension_api.json | 90 | ||||
-rw-r--r-- | chrome/renderer/resources/extension_apitest.js | 14 | ||||
-rw-r--r-- | chrome/renderer/resources/extension_process_bindings.js | 3 | ||||
-rw-r--r-- | chrome/renderer/resources/renderer_extension_bindings.js | 1 | ||||
-rw-r--r-- | chrome/test/data/extensions/api_test/tts/manifest.json | 7 | ||||
-rw-r--r-- | chrome/test/data/extensions/api_test/tts/test.html | 1 | ||||
-rw-r--r-- | chrome/test/data/extensions/api_test/tts/test.js | 31 |
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 |