diff options
author | shuchen@chromium.org <shuchen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-06-12 07:48:09 +0000 |
---|---|---|
committer | shuchen@chromium.org <shuchen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-06-12 07:48:09 +0000 |
commit | 28611342270e8a469664f549fdae78397325919e (patch) | |
tree | 7d284b264064084af3e208b4133f9bb35af32610 | |
parent | 4b6bc8c9a9aa620154317ff64dc34680e474e5ee (diff) | |
download | chromium_src-28611342270e8a469664f549fdae78397325919e.zip chromium_src-28611342270e8a469664f549fdae78397325919e.tar.gz chromium_src-28611342270e8a469664f549fdae78397325919e.tar.bz2 |
Adds IME switching private APIs.
BUG=372291
TEST=None
Review URL: https://codereview.chromium.org/305533002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@276570 0039d316-1c4b-4281-b951-d872f2087c98
7 files changed, 188 insertions, 101 deletions
diff --git a/chrome/browser/chromeos/extensions/input_method_api.cc b/chrome/browser/chromeos/extensions/input_method_api.cc index 582f8e1..5950d46 100644 --- a/chrome/browser/chromeos/extensions/input_method_api.cc +++ b/chrome/browser/chromeos/extensions/input_method_api.cc @@ -9,9 +9,11 @@ #include "chrome/browser/chromeos/extensions/input_method_event_router.h" #include "chrome/browser/extensions/api/input_ime/input_ime_api.h" #include "chromeos/ime/extension_ime_util.h" +#include "chromeos/ime/input_method_descriptor.h" #include "chromeos/ime/input_method_manager.h" #include "extensions/browser/extension_function_registry.h" #include "extensions/browser/extension_system.h" +#include "extensions/common/value_builder.h" namespace { @@ -22,42 +24,57 @@ const char kXkbPrefix[] = "xkb:"; namespace extensions { -GetInputMethodFunction::GetInputMethodFunction() { -} - -GetInputMethodFunction::~GetInputMethodFunction() { -} - -bool GetInputMethodFunction::RunSync() { +ExtensionFunction::ResponseAction GetCurrentInputMethodFunction::Run() { #if !defined(OS_CHROMEOS) - NOTREACHED(); - return false; + EXTENSION_FUNCTION_VALIDATE(false); #else chromeos::input_method::InputMethodManager* manager = chromeos::input_method::InputMethodManager::Get(); - const std::string input_method = InputMethodAPI::GetInputMethodForXkb( - manager->GetCurrentInputMethod().id()); - SetResult(base::Value::CreateStringValue(input_method)); - return true; + return RespondNow(OneArgument( + new base::StringValue(manager->GetCurrentInputMethod().id()))); #endif } -StartImeFunction::StartImeFunction() { -} - -StartImeFunction::~StartImeFunction() { +ExtensionFunction::ResponseAction SetCurrentInputMethodFunction::Run() { +#if !defined(OS_CHROMEOS) + EXTENSION_FUNCTION_VALIDATE(false); +#else + std::string new_input_method; + EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &new_input_method)); + chromeos::input_method::InputMethodManager* manager = + chromeos::input_method::InputMethodManager::Get(); + const std::vector<std::string>& input_methods = + manager->GetActiveInputMethodIds(); + for (size_t i = 0; i < input_methods.size(); ++i) { + const std::string& input_method = input_methods[i]; + if (input_method == new_input_method) { + manager->ChangeInputMethod(new_input_method); + return RespondNow(NoArguments()); + } + } + return RespondNow(Error("Invalid input method id.")); +#endif } -bool StartImeFunction::RunSync() { +ExtensionFunction::ResponseAction GetInputMethodsFunction::Run() { #if !defined(OS_CHROMEOS) - NOTREACHED(); - return false; + EXTENSION_FUNCTION_VALIDATE(false); #else - chromeos::InputMethodEngineInterface* engine = - InputImeEventRouter::GetInstance()->GetActiveEngine(extension_id()); - if (engine) - engine->NotifyImeReady(); - return true; + base::ListValue* output = new base::ListValue(); + chromeos::input_method::InputMethodManager* manager = + chromeos::input_method::InputMethodManager::Get(); + scoped_ptr<chromeos::input_method::InputMethodDescriptors> input_methods = + manager->GetActiveInputMethods(); + for (size_t i = 0; i < input_methods->size(); ++i) { + const chromeos::input_method::InputMethodDescriptor& input_method = + (*input_methods)[i]; + base::DictionaryValue* val = new base::DictionaryValue(); + val->SetString("id", input_method.id()); + val->SetString("name", input_method.name()); + val->SetString("indicator", input_method.indicator()); + output->Append(val); + } + return RespondNow(OneArgument(output)); #endif } @@ -70,8 +87,9 @@ InputMethodAPI::InputMethodAPI(content::BrowserContext* context) EventRouter::Get(context_)->RegisterObserver(this, kOnInputMethodChanged); ExtensionFunctionRegistry* registry = ExtensionFunctionRegistry::GetInstance(); - registry->RegisterFunction<GetInputMethodFunction>(); - registry->RegisterFunction<StartImeFunction>(); + registry->RegisterFunction<GetCurrentInputMethodFunction>(); + registry->RegisterFunction<SetCurrentInputMethodFunction>(); + registry->RegisterFunction<GetInputMethodsFunction>(); } InputMethodAPI::~InputMethodAPI() { diff --git a/chrome/browser/chromeos/extensions/input_method_api.h b/chrome/browser/chromeos/extensions/input_method_api.h index d7a4d7f..77f84e8 100644 --- a/chrome/browser/chromeos/extensions/input_method_api.h +++ b/chrome/browser/chromeos/extensions/input_method_api.h @@ -17,34 +17,49 @@ class ExtensionInputMethodEventRouter; namespace extensions { -// Implements the experimental.inputMethod.get method. -class GetInputMethodFunction : public SyncExtensionFunction { +// Implements the inputMethodPrivate.getCurrentInputMethod method. +class GetCurrentInputMethodFunction : public UIThreadExtensionFunction { public: - GetInputMethodFunction(); + GetCurrentInputMethodFunction() {} protected: - virtual ~GetInputMethodFunction(); + virtual ~GetCurrentInputMethodFunction() {} - virtual bool RunSync() OVERRIDE; + virtual ResponseAction Run() OVERRIDE; private: - DECLARE_EXTENSION_FUNCTION("inputMethodPrivate.get", INPUTMETHODPRIVATE_GET) + DECLARE_EXTENSION_FUNCTION("inputMethodPrivate.getCurrentInputMethod", + INPUTMETHODPRIVATE_GETCURRENTINPUTMETHOD) }; -// Notify the initialization is done to input method engine. -// TODO(nona): remove this function. -class StartImeFunction : public SyncExtensionFunction { +// Implements the inputMethodPrivate.setCurrentInputMethod method. +class SetCurrentInputMethodFunction : public UIThreadExtensionFunction { public: - StartImeFunction(); + SetCurrentInputMethodFunction() {} protected: - virtual ~StartImeFunction(); + virtual ~SetCurrentInputMethodFunction() {} - virtual bool RunSync() OVERRIDE; + virtual ResponseAction Run() OVERRIDE; private: - DECLARE_EXTENSION_FUNCTION("inputMethodPrivate.startIme", - INPUTMETHODPRIVATE_STARTIME) + DECLARE_EXTENSION_FUNCTION("inputMethodPrivate.setCurrentInputMethod", + INPUTMETHODPRIVATE_SETCURRENTINPUTMETHOD) +}; + +// Implements the inputMethodPrivate.getInputMethods method. +class GetInputMethodsFunction : public UIThreadExtensionFunction { + public: + GetInputMethodsFunction() {} + + protected: + virtual ~GetInputMethodsFunction() {} + + virtual ResponseAction Run() OVERRIDE; + + private: + DECLARE_EXTENSION_FUNCTION("inputMethodPrivate.getInputMethods", + INPUTMETHODPRIVATE_GETINPUTMETHODS) }; class InputMethodAPI : public BrowserContextKeyedAPI, diff --git a/chrome/browser/chromeos/extensions/input_method_apitest_chromeos.cc b/chrome/browser/chromeos/extensions/input_method_apitest_chromeos.cc index 5fa5e5b..c8d175e 100644 --- a/chrome/browser/chromeos/extensions/input_method_apitest_chromeos.cc +++ b/chrome/browser/chromeos/extensions/input_method_apitest_chromeos.cc @@ -25,24 +25,17 @@ namespace { const char kLoginScreenUILanguage[] = "fr"; const char kInitialInputMethodOnLoginScreen[] = "xkb:us::eng"; -const char kNewInputMethod[] = "fr::fra"; -const char kSetInputMethodMessage[] = "setInputMethod"; -const char kSetInputMethodDone[] = "done"; const char kBackgroundReady[] = "ready"; -// Class that listens for the JS message then changes input method and replies -// back. -class SetInputMethodListener : public content::NotificationObserver { +// Class that listens for the JS message. +class TestListener : public content::NotificationObserver { public: - // Creates listener, which should reply exactly |count_| times. - explicit SetInputMethodListener(int count) : count_(count) { + explicit TestListener() { registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_TEST_MESSAGE, content::NotificationService::AllSources()); } - virtual ~SetInputMethodListener() { - EXPECT_EQ(0, count_); - } + virtual ~TestListener() {} // Implements the content::NotificationObserver interface. virtual void Observe(int type, @@ -61,28 +54,11 @@ class SetInputMethodListener : public content::NotificationObserver { chromeos::extension_ime_util::GetInputMethodIDByEngineID( kInitialInputMethodOnLoginScreen)); manager->EnableLoginLayouts(kLoginScreenUILanguage, keyboard_layouts); - return; - } - - const std::string expected_message = - base::StringPrintf("%s:%s", kSetInputMethodMessage, kNewInputMethod); - if (content == expected_message) { - chromeos::input_method::InputMethodManager::Get()->ChangeInputMethod( - chromeos::extension_ime_util::GetInputMethodIDByEngineID( - base::StringPrintf("xkb:%s", kNewInputMethod))); - - scoped_refptr<extensions::TestSendMessageFunction> function = - content::Source<extensions::TestSendMessageFunction>( - source).ptr(); - EXPECT_GT(count_--, 0); - function->Reply(kSetInputMethodDone); } } private: content::NotificationRegistrar registrar_; - - int count_; }; class ExtensionInputMethodApiTest : public ExtensionApiTest { @@ -97,8 +73,8 @@ class ExtensionInputMethodApiTest : public ExtensionApiTest { } // namespace IN_PROC_BROWSER_TEST_F(ExtensionInputMethodApiTest, Basic) { - // Two test, two calls. See JS code for more info. - SetInputMethodListener listener(2); + // Listener for extension's background ready. + TestListener listener; ASSERT_TRUE(RunExtensionTest("input_method")) << message_; } diff --git a/chrome/common/extensions/api/input_method_private.json b/chrome/common/extensions/api/input_method_private.json index 9b40b62..0d11f64 100644 --- a/chrome/common/extensions/api/input_method_private.json +++ b/chrome/common/extensions/api/input_method_private.json @@ -9,7 +9,34 @@ "description": "none", "functions": [ { - "name": "get", + "name": "getInputMethods", + "type": "function", + "description": "Gets all whitelisted input methods.", + "parameters": [ + { + "name": "callback", + "type": "function", + "optional": false, + "description": "Callback which is called with the input method objects.", + "parameters": [ + { + "name": "inputMethods", + "type": "array", + "description": "Whitelisted input method objects.", + "items": { + "type": "object", + "properties": { + "id": {"type": "string"}, + "name": {"type": "string"}, + "indicator": {"type": "string"} + } + } + } + ] + } + ] + }, { + "name": "getCurrentInputMethod", "type": "function", "description": "Gets the current input method.", "parameters": [ @@ -28,10 +55,24 @@ } ] }, { - "name": "startIme", + "name": "setCurrentInputMethod", "type": "function", - "description": "Notify to input method engine to be ready to accept events.", - "parameters" : [] + "description": "Sets the current input method.", + "parameters": [ + { + "name": "inputMethodId", + "type": "string", + "optional": false, + "description": "The input method ID to be set as current input method." + }, + { + "name": "callback", + "type": "function", + "optional": true, + "description": "Callback which is called once the current input method is set or error occurs.", + "parameters": [] + } + ] } ], "events": [ diff --git a/chrome/test/data/extensions/api_test/input_method/background.js b/chrome/test/data/extensions/api_test/input_method/background.js index 2102fb3..3ae7561 100644 --- a/chrome/test/data/extensions/api_test/input_method/background.js +++ b/chrome/test/data/extensions/api_test/input_method/background.js @@ -2,37 +2,68 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -var kNewInputMethod = "fr::fra"; - -function setAndGetTest() { - console.log('Changing input method to: ' + kNewInputMethod); - chrome.test.sendMessage('setInputMethod:' + kNewInputMethod, - function (response) { - chrome.test.assertEq('done', response); - console.log('Getting current input method.'); - chrome.inputMethodPrivate.get(function (inputMethod) { - chrome.test.assertEq(kNewInputMethod, inputMethod); - chrome.test.succeed(); - } - ); +var kOldInputMethod = "_comp_ime_fgoepimhcoialccpbmpnnblemnepkkaoxkb:us::eng"; +var kNewInputMethod = "_comp_ime_fgoepimhcoialccpbmpnnblemnepkkaoxkb:fr::fra"; +var kInvalidInputMethod = "xx::xxx"; + +// The tests needs to be executed in order. + +function setTest() { + console.log('setTest: Changing input method to: ' + kNewInputMethod); + chrome.inputMethodPrivate.setCurrentInputMethod(kNewInputMethod, + function() { + chrome.test.assertTrue(!chrome.runtime.lastError); + chrome.test.succeed(); + }); +} + +function getTest() { + console.log('getTest: Getting current input method.'); + chrome.inputMethodPrivate.getCurrentInputMethod(function(inputMethod) { + chrome.test.assertEq(kNewInputMethod, inputMethod); + chrome.test.succeed(); }); } -function setAndObserveTest() { - console.log('Adding input method event listener.'); - chrome.inputMethodPrivate.onChanged.addListener( - function(newInputMethod) { - chrome.test.assertEq(kNewInputMethod, newInputMethod); +function observeTest() { + console.log('observeTest: Adding input method event listener.'); + chrome.inputMethodPrivate.onChanged.addListener(function(subfix) { + chrome.test.assertEq('us::eng', subfix); + chrome.test.succeed(); + }); + console.log('observeTest: Changing input method to: ' + kOldInputMethod); + chrome.inputMethodPrivate.setCurrentInputMethod(kOldInputMethod); +} + + +function setInvalidTest() { + console.log( + 'setInvalidTest: Changing input method to: ' + kInvalidInputMethod); + chrome.inputMethodPrivate.setCurrentInputMethod(kInvalidInputMethod, + function() { + chrome.test.assertTrue(!!chrome.runtime.lastError); chrome.test.succeed(); + }); +} + +function getListTest() { + console.log('getListTest: Getting input method list.'); + chrome.inputMethodPrivate.getInputMethods(function(inputMethods) { + chrome.test.assertEq(6, inputMethods.length); + var foundOldInputMethod = false; + var foundNewInputMethod = false; + for (var i = 0; i < inputMethods.length; ++i) { + if (inputMethods[i].id == kOldInputMethod) + foundOldInputMethod = true; + if (inputMethods[i].id == kNewInputMethod) + foundNewInputMethod = true; } - ); - console.log('Changing input method to: ' + kNewInputMethod); - chrome.test.sendMessage('setInputMethod:' + kNewInputMethod, - function (response) { - chrome.test.assertEq('done', response); - } - ); + chrome.test.assertTrue(foundOldInputMethod); + chrome.test.assertTrue(foundNewInputMethod); + chrome.test.succeed(); + }); } chrome.test.sendMessage('ready'); -chrome.test.runTests([setAndGetTest, setAndObserveTest]); +chrome.test.runTests( + [setTest, getTest, observeTest, setInvalidTest, getListTest]); diff --git a/extensions/browser/extension_function_histogram_value.h b/extensions/browser/extension_function_histogram_value.h index 2efdc08..291fd10 100644 --- a/extensions/browser/extension_function_histogram_value.h +++ b/extensions/browser/extension_function_histogram_value.h @@ -846,6 +846,9 @@ enum HistogramValue { MANAGEMENT_GENERATEAPPFORLINK, GUESTVIEWINTERNAL_ALLOCATEINSTANCEID, WEBVIEW_NAVIGATE, + INPUTMETHODPRIVATE_GETCURRENTINPUTMETHOD, + INPUTMETHODPRIVATE_SETCURRENTINPUTMETHOD, + INPUTMETHODPRIVATE_GETINPUTMETHODS, // Last entry: Add new entries above and ensure to update // tools/metrics/histograms/histograms/histograms.xml. ENUM_BOUNDARY diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 222c60fda7..f6ff5a6 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml @@ -35973,6 +35973,9 @@ Therefore, the affected-histogram name has to have at least one dot in it. <int value="785" label="MANAGEMENT_GENERATEAPPFORLINK"/> <int value="786" label="GUESTVIEWINTERNAL_ALLOCATEINSTANCEID"/> <int value="787" label="WEBVIEW_NAVIGATE"/> + <int value="788" label="INPUTMETHODPRIVATE_GETCURRENTINPUTMETHOD"/> + <int value="789" label="INPUTMETHODPRIVATE_SETCURRENTINPUTMETHOD"/> + <int value="790" label="INPUTMETHODPRIVATE_GETINPUTMETHODS"/> </enum> <enum name="ExtensionInstallCause" type="int"> |