Commit 372ba214 authored by shuchen@chromium.org's avatar shuchen@chromium.org

[IME] Removes the duplicated IMEs in chrome://settings/languages, and support...

[IME] Removes the duplicated IMEs in chrome://settings/languages, and support async component IMEs loading in oobe network screen, and fix the wrong indicator issue.

BUG=345604,349829
TEST=None
TBR=nona@chromium.org

Review URL: https://codereview.chromium.org/190033005

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@255879 0039d316-1c4b-4281-b951-d872f2087c98
parent 0f8f5b47
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "chrome/browser/chromeos/extensions/input_method_event_router.h" #include "chrome/browser/chromeos/extensions/input_method_event_router.h"
#include "chrome/browser/extensions/api/input_ime/input_ime_api.h" #include "chrome/browser/extensions/api/input_ime/input_ime_api.h"
#include "chrome/browser/extensions/event_names.h" #include "chrome/browser/extensions/event_names.h"
#include "chromeos/ime/extension_ime_util.h"
#include "chromeos/ime/input_method_manager.h" #include "chromeos/ime/input_method_manager.h"
#include "extensions/browser/extension_function_registry.h" #include "extensions/browser/extension_function_registry.h"
#include "extensions/browser/extension_system.h" #include "extensions/browser/extension_system.h"
...@@ -76,8 +77,11 @@ InputMethodAPI::~InputMethodAPI() { ...@@ -76,8 +77,11 @@ InputMethodAPI::~InputMethodAPI() {
// static // static
std::string InputMethodAPI::GetInputMethodForXkb(const std::string& xkb_id) { std::string InputMethodAPI::GetInputMethodForXkb(const std::string& xkb_id) {
size_t prefix_length = std::string(kXkbPrefix).length(); std::string xkb_prefix =
DCHECK(xkb_id.substr(0, prefix_length) == kXkbPrefix); chromeos::extension_ime_util::GetInputMethodIDByKeyboardLayout(
kXkbPrefix);
size_t prefix_length = xkb_prefix.length();
DCHECK(xkb_id.substr(0, prefix_length) == xkb_prefix);
return xkb_id.substr(prefix_length); return xkb_id.substr(prefix_length);
} }
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "base/strings/stringprintf.h" #include "base/strings/stringprintf.h"
#include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/chromeos/extensions/input_method_event_router.h" #include "chrome/browser/chromeos/extensions/input_method_event_router.h"
#include "chrome/browser/chromeos/input_method/input_method_util.h"
#include "chrome/browser/extensions/api/test/test_api.h" #include "chrome/browser/extensions/api/test/test_api.h"
#include "chrome/common/chrome_switches.h" #include "chrome/common/chrome_switches.h"
#include "chromeos/ime/extension_ime_util.h" #include "chromeos/ime/extension_ime_util.h"
...@@ -27,6 +28,7 @@ const char kInitialInputMethodOnLoginScreen[] = "xkb:us::eng"; ...@@ -27,6 +28,7 @@ const char kInitialInputMethodOnLoginScreen[] = "xkb:us::eng";
const char kNewInputMethod[] = "fr::fra"; const char kNewInputMethod[] = "fr::fra";
const char kSetInputMethodMessage[] = "setInputMethod"; const char kSetInputMethodMessage[] = "setInputMethod";
const char kSetInputMethodDone[] = "done"; const char kSetInputMethodDone[] = "done";
const char kBackgroundReady[] = "ready";
// Class that listens for the JS message then changes input method and replies // Class that listens for the JS message then changes input method and replies
// back. // back.
...@@ -36,10 +38,6 @@ class SetInputMethodListener : public content::NotificationObserver { ...@@ -36,10 +38,6 @@ class SetInputMethodListener : public content::NotificationObserver {
explicit SetInputMethodListener(int count) : count_(count) { explicit SetInputMethodListener(int count) : count_(count) {
registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_TEST_MESSAGE, registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_TEST_MESSAGE,
content::NotificationService::AllSources()); content::NotificationService::AllSources());
std::vector<std::string> keyboard_layouts;
keyboard_layouts.push_back(kInitialInputMethodOnLoginScreen);
chromeos::input_method::InputMethodManager::Get()->EnableLoginLayouts(
kLoginScreenUILanguage, keyboard_layouts);
} }
virtual ~SetInputMethodListener() { virtual ~SetInputMethodListener() {
...@@ -51,11 +49,27 @@ class SetInputMethodListener : public content::NotificationObserver { ...@@ -51,11 +49,27 @@ class SetInputMethodListener : public content::NotificationObserver {
const content::NotificationSource& source, const content::NotificationSource& source,
const content::NotificationDetails& details) OVERRIDE { const content::NotificationDetails& details) OVERRIDE {
const std::string& content = *content::Details<std::string>(details).ptr(); const std::string& content = *content::Details<std::string>(details).ptr();
if (content == kBackgroundReady) {
// Initializes IMF for testing when receives ready message from
// background.
chromeos::input_method::InputMethodManager* manager =
chromeos::input_method::InputMethodManager::Get();
manager->GetInputMethodUtil()->InitXkbInputMethodsForTesting();
std::vector<std::string> keyboard_layouts;
keyboard_layouts.push_back(
chromeos::extension_ime_util::GetInputMethodIDByKeyboardLayout(
kInitialInputMethodOnLoginScreen));
manager->EnableLoginLayouts(kLoginScreenUILanguage, keyboard_layouts);
return;
}
const std::string expected_message = const std::string expected_message =
base::StringPrintf("%s:%s", kSetInputMethodMessage, kNewInputMethod); base::StringPrintf("%s:%s", kSetInputMethodMessage, kNewInputMethod);
if (content == expected_message) { if (content == expected_message) {
chromeos::input_method::InputMethodManager::Get()-> chromeos::input_method::InputMethodManager::Get()->ChangeInputMethod(
ChangeInputMethod(base::StringPrintf("xkb:%s", kNewInputMethod)); chromeos::extension_ime_util::GetInputMethodIDByKeyboardLayout(
base::StringPrintf("xkb:%s", kNewInputMethod)));
scoped_refptr<extensions::TestSendMessageFunction> function = scoped_refptr<extensions::TestSendMessageFunction> function =
content::Source<extensions::TestSendMessageFunction>( content::Source<extensions::TestSendMessageFunction>(
...@@ -82,9 +96,6 @@ class ExtensionInputMethodApiTest : public ExtensionApiTest { ...@@ -82,9 +96,6 @@ class ExtensionInputMethodApiTest : public ExtensionApiTest {
} // namespace } // namespace
IN_PROC_BROWSER_TEST_F(ExtensionInputMethodApiTest, Basic) { IN_PROC_BROWSER_TEST_F(ExtensionInputMethodApiTest, Basic) {
chromeos::extension_ime_util::ScopedUseExtensionKeyboardFlagForTesting
scoped_flag(false);
// Two test, two calls. See JS code for more info. // Two test, two calls. See JS code for more info.
SetInputMethodListener listener(2); SetInputMethodListener listener(2);
......
...@@ -112,7 +112,11 @@ void InputMethodManagerImpl::SetState(State new_state) { ...@@ -112,7 +112,11 @@ void InputMethodManagerImpl::SetState(State new_state) {
scoped_ptr<InputMethodDescriptors> scoped_ptr<InputMethodDescriptors>
InputMethodManagerImpl::GetSupportedInputMethods() const { InputMethodManagerImpl::GetSupportedInputMethods() const {
return whitelist_.GetSupportedInputMethods(); scoped_ptr<InputMethodDescriptors> whitelist_imes =
whitelist_.GetSupportedInputMethods();
if (!extension_ime_util::UseWrappedExtensionKeyboardLayouts())
return whitelist_imes.Pass();
return scoped_ptr<InputMethodDescriptors>(new InputMethodDescriptors).Pass();
} }
scoped_ptr<InputMethodDescriptors> scoped_ptr<InputMethodDescriptors>
...@@ -246,17 +250,12 @@ bool InputMethodManagerImpl::EnableInputMethodImpl( ...@@ -246,17 +250,12 @@ bool InputMethodManagerImpl::EnableInputMethodImpl(
// Starts or stops the system input method framework as needed. // Starts or stops the system input method framework as needed.
void InputMethodManagerImpl::ReconfigureIMFramework() { void InputMethodManagerImpl::ReconfigureIMFramework() {
if (component_extension_ime_manager_->IsInitialized()) LoadNecessaryComponentExtensions();
LoadNecessaryComponentExtensions();
const bool need_engine =
!ContainsOnlyKeyboardLayout(active_input_method_ids_);
// Initialize candidate window controller and widgets such as // Initialize candidate window controller and widgets such as
// candidate window, infolist and mode indicator. Note, mode // candidate window, infolist and mode indicator. Note, mode
// indicator is used by only keyboard layout input methods. // indicator is used by only keyboard layout input methods.
if (need_engine || active_input_method_ids_.size() > 1) MaybeInitializeCandidateWindowController();
MaybeInitializeCandidateWindowController();
} }
bool InputMethodManagerImpl::EnableInputMethod( bool InputMethodManagerImpl::EnableInputMethod(
...@@ -352,7 +351,9 @@ bool InputMethodManagerImpl::ChangeInputMethodInternal( ...@@ -352,7 +351,9 @@ bool InputMethodManagerImpl::ChangeInputMethodInternal(
engine->Disable(); engine->Disable();
// Configure the next engine handler. // Configure the next engine handler.
if (InputMethodUtil::IsKeyboardLayout(input_method_id_to_switch)) { if (InputMethodUtil::IsKeyboardLayout(input_method_id_to_switch) &&
!extension_ime_util::IsKeyboardLayoutExtension(
input_method_id_to_switch)) {
IMEBridge::Get()->SetCurrentEngineHandler(NULL); IMEBridge::Get()->SetCurrentEngineHandler(NULL);
} else { } else {
IMEEngineHandlerInterface* next_engine = IMEEngineHandlerInterface* next_engine =
...@@ -425,9 +426,8 @@ void InputMethodManagerImpl::LoadNecessaryComponentExtensions() { ...@@ -425,9 +426,8 @@ void InputMethodManagerImpl::LoadNecessaryComponentExtensions() {
// some component extension IMEs may have been removed from the Chrome OS // some component extension IMEs may have been removed from the Chrome OS
// image. If specified component extension IME no longer exists, falling back // image. If specified component extension IME no longer exists, falling back
// to an existing IME. // to an existing IME.
std::vector<std::string> unfiltered_input_method_ids = std::vector<std::string> unfiltered_input_method_ids;
active_input_method_ids_; unfiltered_input_method_ids.swap(active_input_method_ids_);
active_input_method_ids_.clear();
for (size_t i = 0; i < unfiltered_input_method_ids.size(); ++i) { for (size_t i = 0; i < unfiltered_input_method_ids.size(); ++i) {
if (!extension_ime_util::IsComponentExtensionIME( if (!extension_ime_util::IsComponentExtensionIME(
unfiltered_input_method_ids[i])) { unfiltered_input_method_ids[i])) {
...@@ -440,6 +440,8 @@ void InputMethodManagerImpl::LoadNecessaryComponentExtensions() { ...@@ -440,6 +440,8 @@ void InputMethodManagerImpl::LoadNecessaryComponentExtensions() {
active_input_method_ids_.push_back(unfiltered_input_method_ids[i]); active_input_method_ids_.push_back(unfiltered_input_method_ids[i]);
} }
} }
// TODO(shuchen): move this call in ComponentExtensionIMEManager.
component_extension_ime_manager_->NotifyInitialized();
} }
void InputMethodManagerImpl::ActivateInputMethodMenuItem( void InputMethodManagerImpl::ActivateInputMethodMenuItem(
...@@ -835,15 +837,6 @@ bool InputMethodManagerImpl::InputMethodIsActivated( ...@@ -835,15 +837,6 @@ bool InputMethodManagerImpl::InputMethodIsActivated(
return Contains(active_input_method_ids_, input_method_id); return Contains(active_input_method_ids_, input_method_id);
} }
bool InputMethodManagerImpl::ContainsOnlyKeyboardLayout(
const std::vector<std::string>& value) {
for (size_t i = 0; i < value.size(); ++i) {
if (!InputMethodUtil::IsKeyboardLayout(value[i]))
return false;
}
return true;
}
void InputMethodManagerImpl::MaybeInitializeCandidateWindowController() { void InputMethodManagerImpl::MaybeInitializeCandidateWindowController() {
if (candidate_window_controller_.get()) if (candidate_window_controller_.get())
return; return;
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
// For SetHardwareKeyboardLayoutForTesting. // For SetHardwareKeyboardLayoutForTesting.
#include "chromeos/ime/fake_input_method_delegate.h" #include "chromeos/ime/fake_input_method_delegate.h"
#include "chromeos/ime/input_method_delegate.h" #include "chromeos/ime/input_method_delegate.h"
#include "chromeos/ime/input_method_whitelist.h"
// TODO(nona): move this header from this file. // TODO(nona): move this header from this file.
#include "grit/generated_resources.h" #include "grit/generated_resources.h"
...@@ -126,6 +127,61 @@ const struct { ...@@ -126,6 +127,61 @@ const struct {
{ "vi", "us", "_comp_ime_jhffeifommiaekmbkkjlpmilogcfdohpvkd_vi_tcvn" }, { "vi", "us", "_comp_ime_jhffeifommiaekmbkkjlpmilogcfdohpvkd_vi_tcvn" },
}; };
// The map from xkb layout to the indicator text.
// Refer to crbug.com/349829.
const char* const kXkbIndicators[][2] = {{"am", "AM"},
{"be", "BE"},
{"bg", "BG"},
{"bg(phonetic)", "BG"},
{"br", "BR"},
{"by", "BY"},
{"ca", "CA"},
{"ca(eng)", "CA"},
{"ca(multix)", "CA"},
{"ch", "CH"},
{"ch(fr)", "CH"},
{"cz", "CZ"},
{"cz(qwerty)", "CS"},
{"de", "DE"},
{"de(neo)", "NEO"},
{"dk", "DK"},
{"ee", "EE"},
{"es", "ES"},
{"es(cat)", "CAS"},
{"fi", "FI"},
{"fr", "FR"},
{"gb(dvorak)", "DV"},
{"gb(extd)", "GB"},
{"ge", "GE"},
{"gr", "GR"},
{"hr", "HR"},
{"hu", "HU"},
{"il", "IL"},
{"is", "IS"},
{"it", "IT"},
{"jp", "JA"},
{"latam", "LA"},
{"lt", "LT"},
{"lv(apostrophe)", "LV"},
{"mn", "MN"},
{"no", "NO"},
{"pl", "PL"},
{"pt", "PT"},
{"ro", "RO"},
{"rs", "RS"},
{"ru", "RU"},
{"ru(phonetic)", "RU"},
{"se", "SE"},
{"si", "SI"},
{"sk", "SK"},
{"tr", "TR"},
{"ua", "UA"},
{"us", "US"},
{"us(altgr-intl)", "EXTD"},
{"us(colemak)", "CO"},
{"us(dvorak)", "DV"},
{"us(intl)", "INTL"}, };
} // namespace } // namespace
namespace chromeos { namespace chromeos {
...@@ -291,6 +347,11 @@ InputMethodUtil::InputMethodUtil( ...@@ -291,6 +347,11 @@ InputMethodUtil::InputMethodUtil(
scoped_ptr<InputMethodDescriptors> supported_input_methods) scoped_ptr<InputMethodDescriptors> supported_input_methods)
: supported_input_methods_(supported_input_methods.Pass()), : supported_input_methods_(supported_input_methods.Pass()),
delegate_(delegate) { delegate_(delegate) {
// Makes sure the supported input methods at least have the fallback ime.
// So that it won't cause massive test failures.
if (supported_input_methods_->empty())
supported_input_methods_->push_back(GetFallbackInputMethodDescriptor());
ReloadInternalMaps(); ReloadInternalMaps();
// Initialize a map from English string to Chrome string resource ID as well. // Initialize a map from English string to Chrome string resource ID as well.
...@@ -301,6 +362,11 @@ InputMethodUtil::InputMethodUtil( ...@@ -301,6 +362,11 @@ InputMethodUtil::InputMethodUtil(
DCHECK(result) << "Duplicated string is found: " DCHECK(result) << "Duplicated string is found: "
<< map_entry.english_string_from_ibus; << map_entry.english_string_from_ibus;
} }
// Initialize the map from xkb layout to indicator text.
for (size_t i = 0; i < arraysize(kXkbIndicators); ++i) {
xkb_layout_to_indicator_[kXkbIndicators[i][0]] = kXkbIndicators[i][1];
}
} }
InputMethodUtil::~InputMethodUtil() { InputMethodUtil::~InputMethodUtil() {
...@@ -398,13 +464,11 @@ base::string16 InputMethodUtil::GetInputMethodShortName( ...@@ -398,13 +464,11 @@ base::string16 InputMethodUtil::GetInputMethodShortName(
} }
// Display the keyboard layout name when using a keyboard layout. // Display the keyboard layout name when using a keyboard layout.
if (text.empty() && if (text.empty() && IsKeyboardLayout(input_method.id())) {
IsKeyboardLayout(input_method.id())) { std::map<std::string, std::string>::const_iterator it =
const size_t kMaxKeyboardLayoutNameLen = 2; xkb_layout_to_indicator_.find(GetKeyboardLayoutName(input_method.id()));
const base::string16 keyboard_layout = if (it != xkb_layout_to_indicator_.end())
base::UTF8ToUTF16(GetKeyboardLayoutName(input_method.id())); text = base::UTF8ToUTF16(it->second);
text = StringToUpperASCII(keyboard_layout).substr(
0, kMaxKeyboardLayoutNameLen);
} }
// TODO(yusukes): Some languages have two or more input methods. For example, // TODO(yusukes): Some languages have two or more input methods. For example,
...@@ -481,21 +545,10 @@ base::string16 InputMethodUtil::GetInputMethodLongName( ...@@ -481,21 +545,10 @@ base::string16 InputMethodUtil::GetInputMethodLongName(
const InputMethodDescriptor* InputMethodUtil::GetInputMethodDescriptorFromId( const InputMethodDescriptor* InputMethodUtil::GetInputMethodDescriptorFromId(
const std::string& input_method_id) const { const std::string& input_method_id) const {
InputMethodIdToDescriptorMap::const_iterator iter InputMethodIdToDescriptorMap::const_iterator iter =
= id_to_descriptor_.find(input_method_id); id_to_descriptor_.find(input_method_id);
if (iter == id_to_descriptor_.end()) { if (iter == id_to_descriptor_.end())
// If failed to find the descriptor for given id, it may because of the id return NULL;
// is a component extension xkb id (_comp_ime_...xkb:...).
// So try to convert it to legacy xkb id and find again.
// This hack is mainly for OOBE session, which requires a sync call to get
// the input method descriptor for extension xkb id.
// TODO(shuchen): need to support async wait for component extension
// loading in OOBE session. This hack won't be needed when it's been done.
iter = id_to_descriptor_.find(
extension_ime_util::MaybeGetLegacyXkbId(input_method_id));
if (iter == id_to_descriptor_.end())
return NULL;
}
return &(iter->second); return &(iter->second);
} }
...@@ -708,16 +761,49 @@ bool InputMethodUtil::IsLoginKeyboard(const std::string& input_method_id) ...@@ -708,16 +761,49 @@ bool InputMethodUtil::IsLoginKeyboard(const std::string& input_method_id)
void InputMethodUtil::SetComponentExtensions( void InputMethodUtil::SetComponentExtensions(
const InputMethodDescriptors& imes) { const InputMethodDescriptors& imes) {
component_extension_ime_id_to_descriptor_.clear();
for (size_t i = 0; i < imes.size(); ++i) { for (size_t i = 0; i < imes.size(); ++i) {
const InputMethodDescriptor& input_method = imes.at(i); const InputMethodDescriptor& input_method = imes[i];
DCHECK(!input_method.language_codes().empty()); DCHECK(!input_method.language_codes().empty());
const std::string language_code = input_method.language_codes().at(0); const std::vector<std::string>& language_codes =
id_to_language_code_.insert( input_method.language_codes();
std::make_pair(input_method.id(), language_code)); id_to_language_code_[input_method.id()] = language_codes[0];
id_to_descriptor_.insert( id_to_descriptor_[input_method.id()] = input_method;
std::make_pair(input_method.id(), input_method));
typedef LanguageCodeToIdsMap::const_iterator It;
for (size_t j = 0; j < language_codes.size(); ++j) {
std::pair<It, It> range =
language_code_to_ids_.equal_range(language_codes[j]);
It it = range.first;
for (; it != range.second; ++it) {
if (it->second == input_method.id())
break;
}
if (it == range.second)
language_code_to_ids_.insert(
std::make_pair(language_codes[j], input_method.id()));
}
}
}
void InputMethodUtil::InitXkbInputMethodsForTesting() {
if (!extension_ime_util::UseWrappedExtensionKeyboardLayouts())
return;
scoped_ptr<InputMethodDescriptors> original_imes =
InputMethodWhitelist().GetSupportedInputMethods();
InputMethodDescriptors whitelist_imes;
for (size_t i = 0; i < original_imes->size(); ++i) {
const InputMethodDescriptor& ime = (*original_imes)[i];
whitelist_imes.push_back(InputMethodDescriptor(
extension_ime_util::GetInputMethodIDByKeyboardLayout(ime.id()),
"",
ime.indicator(),
ime.keyboard_layouts(),
ime.language_codes(),
ime.is_login_keyboard(),
ime.options_page_url(),
ime.input_view_url()));
} }
SetComponentExtensions(whitelist_imes);
} }
InputMethodDescriptor InputMethodUtil::GetFallbackInputMethodDescriptor() { InputMethodDescriptor InputMethodUtil::GetFallbackInputMethodDescriptor() {
......
...@@ -140,6 +140,9 @@ class InputMethodUtil { ...@@ -140,6 +140,9 @@ class InputMethodUtil {
// Sets the list of component extension IMEs. // Sets the list of component extension IMEs.
void SetComponentExtensions(const InputMethodDescriptors& imes); void SetComponentExtensions(const InputMethodDescriptors& imes);
// Initializes the extension based xkb IMEs for testing.
void InitXkbInputMethodsForTesting();
// Returns the fallback input method descriptor (the very basic US // Returns the fallback input method descriptor (the very basic US
// keyboard). This function is mostly used for testing, but may be used // keyboard). This function is mostly used for testing, but may be used
// as the fallback, when there is no other choice. // as the fallback, when there is no other choice.
...@@ -190,7 +193,7 @@ class InputMethodUtil { ...@@ -190,7 +193,7 @@ class InputMethodUtil {
std::map<std::string, std::string> id_to_language_code_; std::map<std::string, std::string> id_to_language_code_;
InputMethodIdToDescriptorMap id_to_descriptor_; InputMethodIdToDescriptorMap id_to_descriptor_;
XkbIdToDescriptorMap xkb_id_to_descriptor_; XkbIdToDescriptorMap xkb_id_to_descriptor_;
ComponentExtIMEMap component_extension_ime_id_to_descriptor_; std::map<std::string, std::string> xkb_layout_to_indicator_;
typedef base::hash_map<std::string, int> HashType; typedef base::hash_map<std::string, int> HashType;
HashType english_to_resource_id_; HashType english_to_resource_id_;
......
...@@ -5,10 +5,13 @@ ...@@ -5,10 +5,13 @@
#include <algorithm> #include <algorithm>
#include "ash/shell.h" #include "ash/shell.h"
#include "chrome/browser/chromeos/input_method/input_method_util.h"
#include "chrome/browser/chromeos/input_method/mode_indicator_controller.h" #include "chrome/browser/chromeos/input_method/mode_indicator_controller.h"
#include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/in_process_browser_test.h"
#include "chromeos/ime/component_extension_ime_manager.h" #include "chromeos/ime/component_extension_ime_manager.h"
#include "chromeos/ime/extension_ime_util.h"
#include "chromeos/ime/input_method_manager.h" #include "chromeos/ime/input_method_manager.h"
#include "chromeos/ime/input_method_whitelist.h"
#include "content/public/test/browser_test_utils.h" #include "content/public/test/browser_test_utils.h"
#include "content/public/test/test_utils.h" #include "content/public/test/test_utils.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
...@@ -96,6 +99,9 @@ class ModeIndicatorBrowserTest : public InProcessBrowserTest { ...@@ -96,6 +99,9 @@ class ModeIndicatorBrowserTest : public InProcessBrowserTest {
} }
void InitializeIMF() { void InitializeIMF() {
InputMethodManager::Get()
->GetInputMethodUtil()
->InitXkbInputMethodsForTesting();
// Make sure ComponentExtensionIMEManager is initialized. // Make sure ComponentExtensionIMEManager is initialized.
// ComponentExtensionIMEManagerImpl::InitializeAsync posts // ComponentExtensionIMEManagerImpl::InitializeAsync posts
// ReadComponentExtensionsInfo to the FILE thread for the // ReadComponentExtensionsInfo to the FILE thread for the
...@@ -126,7 +132,8 @@ IN_PROC_BROWSER_TEST_F(ModeIndicatorBrowserTest, Bounds) { ...@@ -126,7 +132,8 @@ IN_PROC_BROWSER_TEST_F(ModeIndicatorBrowserTest, Bounds) {
ASSERT_TRUE(imm); ASSERT_TRUE(imm);
std::vector<std::string> keyboard_layouts; std::vector<std::string> keyboard_layouts;
keyboard_layouts.push_back("xkb:fr::fra"); keyboard_layouts.push_back(
extension_ime_util::GetInputMethodIDByKeyboardLayout("xkb:fr::fra"));
// Add keyboard layouts to enable the mode indicator. // Add keyboard layouts to enable the mode indicator.
imm->EnableLoginLayouts("fr", keyboard_layouts); imm->EnableLoginLayouts("fr", keyboard_layouts);
...@@ -193,7 +200,8 @@ IN_PROC_BROWSER_TEST_F(ModeIndicatorBrowserTest, NumOfWidgets) { ...@@ -193,7 +200,8 @@ IN_PROC_BROWSER_TEST_F(ModeIndicatorBrowserTest, NumOfWidgets) {
ASSERT_TRUE(imm); ASSERT_TRUE(imm);
std::vector<std::string> keyboard_layouts; std::vector<std::string> keyboard_layouts;
keyboard_layouts.push_back("xkb:fr::fra"); keyboard_layouts.push_back(
extension_ime_util::GetInputMethodIDByKeyboardLayout("xkb:fr::fra"));
// Add keyboard layouts to enable the mode indicator. // Add keyboard layouts to enable the mode indicator.
imm->EnableLoginLayouts("fr", keyboard_layouts); imm->EnableLoginLayouts("fr", keyboard_layouts);
......
...@@ -9,11 +9,15 @@ ...@@ -9,11 +9,15 @@
#include "chrome/browser/browser_process.h" #include "chrome/browser/browser_process.h"
#include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/chromeos/customization_document.h" #include "chrome/browser/chromeos/customization_document.h"
#include "chrome/browser/chromeos/input_method/input_method_util.h"
#include "chrome/browser/chromeos/login/login_display_host_impl.h" #include "chrome/browser/chromeos/login/login_display_host_impl.h"
#include "chrome/browser/chromeos/login/login_wizard.h" #include "chrome/browser/chromeos/login/login_wizard.h"
#include "chrome/browser/chromeos/login/test/js_checker.h" #include "chrome/browser/chromeos/login/test/js_checker.h"
#include "chrome/common/pref_names.h" #include "chrome/common/pref_names.h"
#include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/in_process_browser_test.h"
#include "chromeos/ime/extension_ime_util.h"
#include "chromeos/ime/input_method_manager.h"
#include "chromeos/ime/input_method_whitelist.h"
#include "chromeos/system/statistics_provider.h" #include "chromeos/system/statistics_provider.h"
#include "content/public/browser/notification_service.h" #include "content/public/browser/notification_service.h"
#include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents.h"
...@@ -221,6 +225,24 @@ void OobeLocalizationTest::RunLocalizationTest( ...@@ -221,6 +225,24 @@ void OobeLocalizationTest::RunLocalizationTest(
StartupCustomizationDocument::GetInstance()->Init( StartupCustomizationDocument::GetInstance()->Init(
statistics_provider_.get()); statistics_provider_.get());
input_method::InputMethodManager::Get()
->GetInputMethodUtil()
->InitXkbInputMethodsForTesting();
std::string expected_keyboard_select = expected_keyboard_select_control;
if (extension_ime_util::UseWrappedExtensionKeyboardLayouts()) {
// Modifies the expected keyboard select control options for the new
// extension based xkb id.
size_t pos = 0;
std::string repl_old = "xkb:";
std::string repl_new = "_comp_ime_fgoepimhcoialccpbmpnnblemnepkkaoxkb:";
while ((pos = expected_keyboard_select.find(repl_old, pos)) !=
std::string::npos) {
expected_keyboard_select.replace(pos, repl_old.length(), repl_new);
pos += repl_new.length();
}
}
// Bring up the OOBE network screen. // Bring up the OOBE network screen.
chromeos::ShowLoginWizard(chromeos::WizardController::kNetworkScreenName); chromeos::ShowLoginWizard(chromeos::WizardController::kNetworkScreenName);
content::WindowedNotificationObserver( content::WindowedNotificationObserver(
...@@ -233,15 +255,18 @@ void OobeLocalizationTest::RunLocalizationTest( ...@@ -233,15 +255,18 @@ void OobeLocalizationTest::RunLocalizationTest(
VerifyInitialOptions(kLocaleSelect, expected_locale.c_str(), true); VerifyInitialOptions(kLocaleSelect, expected_locale.c_str(), true);
VerifyInitialOptions(kKeyboardSelect, VerifyInitialOptions(kKeyboardSelect,
expected_keyboard_layout.c_str(), extension_ime_util::GetInputMethodIDByKeyboardLayout(
expected_keyboard_layout).c_str(),
false); false);
// Make sure we have a fallback keyboard. // Make sure we have a fallback keyboard.
VerifyOptionExists(kKeyboardSelect, kUSLayout); VerifyOptionExists(
kKeyboardSelect,
extension_ime_util::GetInputMethodIDByKeyboardLayout(kUSLayout).c_str());
// Note, that sort order is locale-specific, but is unlikely to change. // Note, that sort order is locale-specific, but is unlikely to change.
// Especially for keyboard layouts. // Especially for keyboard layouts.
EXPECT_EQ(expected_keyboard_select_control, DumpOptions(kKeyboardSelect)); EXPECT_EQ(expected_keyboard_select, DumpOptions(kKeyboardSelect));
// Shut down the display host. // Shut down the display host.
chromeos::LoginDisplayHostImpl::default_host()->Finalize(); chromeos::LoginDisplayHostImpl::default_host()->Finalize();
......
...@@ -49,7 +49,7 @@ const char kJsApiNetworkOnLanguageChanged[] = "networkOnLanguageChanged"; ...@@ -49,7 +49,7 @@ const char kJsApiNetworkOnLanguageChanged[] = "networkOnLanguageChanged";
const char kJsApiNetworkOnInputMethodChanged[] = "networkOnInputMethodChanged"; const char kJsApiNetworkOnInputMethodChanged[] = "networkOnInputMethodChanged";
const char kJsApiNetworkOnTimezoneChanged[] = "networkOnTimezoneChanged"; const char kJsApiNetworkOnTimezoneChanged[] = "networkOnTimezoneChanged";
const char kUSlayout[] = "xkb:us::eng"; const char kUSLayout[] = "xkb:us::eng";
const int kDerelectDetectionTimeoutSeconds = 8 * 60 * 60; // 8 hours. const int kDerelectDetectionTimeoutSeconds = 8 * 60 * 60; // 8 hours.
const int kDerelectIdleTimeoutSeconds = 5 * 60; // 5 minutes. const int kDerelectIdleTimeoutSeconds = 5 * 60; // 5 minutes.
...@@ -85,11 +85,20 @@ NetworkScreenHandler::NetworkScreenHandler(CoreOobeActor* core_oobe_actor) ...@@ -85,11 +85,20 @@ NetworkScreenHandler::NetworkScreenHandler(CoreOobeActor* core_oobe_actor)
weak_ptr_factory_(this) { weak_ptr_factory_(this) {
DCHECK(core_oobe_actor_); DCHECK(core_oobe_actor_);
SetupTimeouts(); SetupTimeouts();
input_method::InputMethodManager* manager =
input_method::InputMethodManager::Get();
manager->SetInputMethodLoginDefault();
manager->GetComponentExtensionIMEManager()->AddObserver(this);
} }
NetworkScreenHandler::~NetworkScreenHandler() { NetworkScreenHandler::~NetworkScreenHandler() {
if (screen_) if (screen_)
screen_->OnActorDestroyed(this); screen_->OnActorDestroyed(this);
input_method::InputMethodManager::Get()
->GetComponentExtensionIMEManager()
->RemoveObserver(this);
} }
// NetworkScreenHandler, NetworkScreenActor implementation: -------------------- // NetworkScreenHandler, NetworkScreenActor implementation: --------------------
...@@ -373,11 +382,17 @@ base::ListValue* NetworkScreenHandler::GetLanguageList() { ...@@ -373,11 +382,17 @@ base::ListValue* NetworkScreenHandler::GetLanguageList() {
const std::string app_locale = g_browser_process->GetApplicationLocale(); const std::string app_locale = g_browser_process->GetApplicationLocale();
input_method::InputMethodManager* manager = input_method::InputMethodManager* manager =
input_method::InputMethodManager::Get(); input_method::InputMethodManager::Get();
// GetSupportedInputMethods() never returns NULL. ComponentExtensionIMEManager* comp_manager =
scoped_ptr<input_method::InputMethodDescriptors> descriptors( manager->GetComponentExtensionIMEManager();
manager->GetSupportedInputMethods()); input_method::InputMethodDescriptors descriptors;
if (extension_ime_util::UseWrappedExtensionKeyboardLayouts()) {
if (comp_manager->IsInitialized())
descriptors = comp_manager->GetXkbIMEAsInputMethodDescriptor();
} else {
descriptors = *(manager->GetSupportedInputMethods());
}
base::ListValue* languages_list = base::ListValue* languages_list =
options::CrosLanguageOptionsHandler::GetUILanguageList(*descriptors); options::CrosLanguageOptionsHandler::GetUILanguageList(descriptors);
for (size_t i = 0; i < languages_list->GetSize(); ++i) { for (size_t i = 0; i < languages_list->GetSize(); ++i) {
base::DictionaryValue* language_info = NULL; base::DictionaryValue* language_info = NULL;
if (!languages_list->GetDictionary(i, &language_info)) if (!languages_list->GetDictionary(i, &language_info))
...@@ -422,23 +437,40 @@ base::DictionaryValue* CreateInputMethodsEntry( ...@@ -422,23 +437,40 @@ base::DictionaryValue* CreateInputMethodsEntry(
return input_method.release(); return input_method.release();
} }
void NetworkScreenHandler::OnImeComponentExtensionInitialized() {
input_method::InputMethodManager::Get()->SetInputMethodLoginDefault();
// Refreshes the language and keyboard list once the component extension
// IMEs are initialized.
base::DictionaryValue localized_strings;
static_cast<OobeUI*>(this->web_ui()->GetController())
->GetLocalizedStrings(&localized_strings);
this->core_oobe_actor_->ReloadContent(localized_strings);
this->EnableContinue(this->is_continue_enabled_);
}
// static // static
base::ListValue* NetworkScreenHandler::GetInputMethods() { base::ListValue* NetworkScreenHandler::GetInputMethods() {
base::ListValue* input_methods_list = new base::ListValue; base::ListValue* input_methods_list = new base::ListValue;
input_method::InputMethodManager* manager = input_method::InputMethodManager* manager =
input_method::InputMethodManager::Get(); input_method::InputMethodManager::Get();
input_method::InputMethodUtil* util = manager->GetInputMethodUtil(); input_method::InputMethodUtil* util = manager->GetInputMethodUtil();
if (extension_ime_util::UseWrappedExtensionKeyboardLayouts()) {
ComponentExtensionIMEManager* comp_manager =
manager->GetComponentExtensionIMEManager();
if (!comp_manager->IsInitialized()) {
input_method::InputMethodDescriptor fallback =
util->GetFallbackInputMethodDescriptor();
input_methods_list->Append(
CreateInputMethodsEntry(fallback, fallback.id()));
return input_methods_list;
}
}
scoped_ptr<input_method::InputMethodDescriptors> input_methods( scoped_ptr<input_method::InputMethodDescriptors> input_methods(
manager->GetActiveInputMethods()); manager->GetActiveInputMethods());
// Uses extension_ime_util::MaybeGetLegacyXkbId() to make sure the input const std::string& current_input_method_id =
// method id is in legacy xkb id format (e.g. xkb:us::eng), instead of manager->GetCurrentInputMethod().id();
// extension based xkd id format (e.g. _comp_ime_...xkb:us::eng).
// Same for the rests.
// TODO(shuchen): support wait for component extension loading, and then show
// OOBE window. So that extension_ime_util::MaybeGetLegacyXkbId() can be
// removed.
std::string current_input_method_id = extension_ime_util::MaybeGetLegacyXkbId(
manager->GetCurrentInputMethod().id());
const std::vector<std::string>& hardware_login_input_methods = const std::vector<std::string>& hardware_login_input_methods =
util->GetHardwareLoginInputMethodIds(); util->GetHardwareLoginInputMethodIds();
std::set<std::string> input_methods_added; std::set<std::string> input_methods_added;
...@@ -447,14 +479,12 @@ base::ListValue* NetworkScreenHandler::GetInputMethods() { ...@@ -447,14 +479,12 @@ base::ListValue* NetworkScreenHandler::GetInputMethods() {
hardware_login_input_methods.begin(); hardware_login_input_methods.begin();
i != hardware_login_input_methods.end(); i != hardware_login_input_methods.end();
++i) { ++i) {
// Makes sure the id is in legacy xkb id format.
const std::string id = extension_ime_util::MaybeGetLegacyXkbId(*i);
input_methods_added.insert(id);
const input_method::InputMethodDescriptor* ime = const input_method::InputMethodDescriptor* ime =
util->GetInputMethodDescriptorFromId(id); util->GetInputMethodDescriptorFromId(*i);
DCHECK(ime != NULL); DCHECK(ime != NULL);
// Do not crash in case of misconfiguration. // Do not crash in case of misconfiguration.
if (ime != NULL) { if (ime != NULL) {
input_methods_added.insert(*i);
input_methods_list->Append( input_methods_list->Append(
CreateInputMethodsEntry(*ime, current_input_method_id)); CreateInputMethodsEntry(*ime, current_input_method_id));
} }
...@@ -463,8 +493,7 @@ base::ListValue* NetworkScreenHandler::GetInputMethods() { ...@@ -463,8 +493,7 @@ base::ListValue* NetworkScreenHandler::GetInputMethods() {
bool optgroup_added = false; bool optgroup_added = false;
for (size_t i = 0; i < input_methods->size(); ++i) { for (size_t i = 0; i < input_methods->size(); ++i) {
// Makes sure the id is in legacy xkb id format. // Makes sure the id is in legacy xkb id format.
const std::string& ime_id = extension_ime_util::MaybeGetLegacyXkbId( const std::string& ime_id = (*input_methods)[i].id();
(*input_methods)[i].id());
if (!InsertString(ime_id, input_methods_added)) if (!InsertString(ime_id, input_methods_added))
continue; continue;
if (!optgroup_added) { if (!optgroup_added) {
...@@ -475,9 +504,11 @@ base::ListValue* NetworkScreenHandler::GetInputMethods() { ...@@ -475,9 +504,11 @@ base::ListValue* NetworkScreenHandler::GetInputMethods() {
CreateInputMethodsEntry((*input_methods)[i], current_input_method_id)); CreateInputMethodsEntry((*input_methods)[i], current_input_method_id));
} }
// "xkb:us::eng" should always be in the list of available layouts. // "xkb:us::eng" should always be in the list of available layouts.
if (input_methods_added.count(kUSlayout) == 0) { const std::string& us_keyboard_id =
extension_ime_util::GetInputMethodIDByKeyboardLayout(kUSLayout);
if (input_methods_added.find(us_keyboard_id) == input_methods_added.end()) {
const input_method::InputMethodDescriptor* us_eng_descriptor = const input_method::InputMethodDescriptor* us_eng_descriptor =
util->GetInputMethodDescriptorFromId(kUSlayout); util->GetInputMethodDescriptorFromId(us_keyboard_id);
DCHECK(us_eng_descriptor != NULL); DCHECK(us_eng_descriptor != NULL);
if (!optgroup_added) { if (!optgroup_added) {
optgroup_added = true; optgroup_added = true;
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include "chrome/browser/chromeos/login/screens/network_screen_actor.h" #include "chrome/browser/chromeos/login/screens/network_screen_actor.h"
#include "chrome/browser/chromeos/settings/cros_settings.h" #include "chrome/browser/chromeos/settings/cros_settings.h"
#include "chrome/browser/ui/webui/chromeos/login/base_screen_handler.h" #include "chrome/browser/ui/webui/chromeos/login/base_screen_handler.h"
#include "chromeos/ime/component_extension_ime_manager.h"
#include "ui/gfx/point.h" #include "ui/gfx/point.h"
class PrefRegistrySimple; class PrefRegistrySimple;
...@@ -27,7 +28,8 @@ struct NetworkScreenHandlerOnLanguageChangedCallbackData; ...@@ -27,7 +28,8 @@ struct NetworkScreenHandlerOnLanguageChangedCallbackData;
// WebUI implementation of NetworkScreenActor. It is used to interact with // WebUI implementation of NetworkScreenActor. It is used to interact with
// the welcome screen (part of the page) of the OOBE. // the welcome screen (part of the page) of the OOBE.
class NetworkScreenHandler : public NetworkScreenActor, class NetworkScreenHandler : public NetworkScreenActor,
public BaseScreenHandler { public BaseScreenHandler,
public ComponentExtensionIMEManager::Observer {
public: public:
explicit NetworkScreenHandler(CoreOobeActor* core_oobe_actor); explicit NetworkScreenHandler(CoreOobeActor* core_oobe_actor);
virtual ~NetworkScreenHandler(); virtual ~NetworkScreenHandler();
...@@ -51,6 +53,9 @@ class NetworkScreenHandler : public NetworkScreenActor, ...@@ -51,6 +53,9 @@ class NetworkScreenHandler : public NetworkScreenActor,
// WebUIMessageHandler implementation: // WebUIMessageHandler implementation:
virtual void RegisterMessages() OVERRIDE; virtual void RegisterMessages() OVERRIDE;
// ComponentExtensionIMEManager::Observer implementation:
virtual void OnImeComponentExtensionInitialized() OVERRIDE;
// Registers the preference for derelict state. // Registers the preference for derelict state.
static void RegisterPrefs(PrefRegistrySimple* registry); static void RegisterPrefs(PrefRegistrySimple* registry);
......
...@@ -450,7 +450,7 @@ void CrosLanguageOptionsHandler::InputMethodOptionsOpenCallback( ...@@ -450,7 +450,7 @@ void CrosLanguageOptionsHandler::InputMethodOptionsOpenCallback(
web_contents->GetDelegate()->ActivateContents(web_contents); web_contents->GetDelegate()->ActivateContents(web_contents);
} }
void CrosLanguageOptionsHandler::OnInitialized() { void CrosLanguageOptionsHandler::OnImeComponentExtensionInitialized() {
if (composition_extension_appended_ || !is_page_initialized_) { if (composition_extension_appended_ || !is_page_initialized_) {
// If an option page is not ready to call JavaScript, appending component // If an option page is not ready to call JavaScript, appending component
// extension IMEs will be done in InitializePage function later. // extension IMEs will be done in InitializePage function later.
......
...@@ -95,7 +95,7 @@ class CrosLanguageOptionsHandler ...@@ -95,7 +95,7 @@ class CrosLanguageOptionsHandler
void InputMethodOptionsOpenCallback(const base::ListValue* args); void InputMethodOptionsOpenCallback(const base::ListValue* args);
// ComponentExtensionIMEManager::Observer override. // ComponentExtensionIMEManager::Observer override.
virtual void OnInitialized() OVERRIDE; virtual void OnImeComponentExtensionInitialized() OVERRIDE;
// Gets the list of languages with |descriptors| based on // Gets the list of languages with |descriptors| based on
// |base_language_codes|. // |base_language_codes|.
......
...@@ -11,7 +11,7 @@ function setAndGetTest() { ...@@ -11,7 +11,7 @@ function setAndGetTest() {
chrome.test.assertEq('done', response); chrome.test.assertEq('done', response);
console.log('Getting current input method.'); console.log('Getting current input method.');
chrome.inputMethodPrivate.get(function (inputMethod) { chrome.inputMethodPrivate.get(function (inputMethod) {
chrome.test.assertEq(inputMethod, kNewInputMethod); chrome.test.assertEq(kNewInputMethod, inputMethod);
chrome.test.succeed(); chrome.test.succeed();
} }
); );
...@@ -34,4 +34,5 @@ function setAndObserveTest() { ...@@ -34,4 +34,5 @@ function setAndObserveTest() {
); );
} }
chrome.test.sendMessage('ready');
chrome.test.runTests([setAndGetTest, setAndObserveTest]); chrome.test.runTests([setAndGetTest, setAndObserveTest]);
...@@ -76,7 +76,7 @@ ComponentExtensionIMEManagerDelegate::~ComponentExtensionIMEManagerDelegate() { ...@@ -76,7 +76,7 @@ ComponentExtensionIMEManagerDelegate::~ComponentExtensionIMEManagerDelegate() {
} }
ComponentExtensionIMEManager::ComponentExtensionIMEManager() ComponentExtensionIMEManager::ComponentExtensionIMEManager()
: is_initialized_(false) { : is_initialized_(false), was_initialization_notified_(false) {
for (size_t i = 0; i < arraysize(kLoginLayoutWhitelist); ++i) { for (size_t i = 0; i < arraysize(kLoginLayoutWhitelist); ++i) {
login_layout_set_.insert(kLoginLayoutWhitelist[i]); login_layout_set_.insert(kLoginLayoutWhitelist[i]);
} }
...@@ -90,7 +90,14 @@ void ComponentExtensionIMEManager::Initialize( ...@@ -90,7 +90,14 @@ void ComponentExtensionIMEManager::Initialize(
delegate_ = delegate.Pass(); delegate_ = delegate.Pass();
component_extension_imes_ = delegate_->ListIME(); component_extension_imes_ = delegate_->ListIME();
is_initialized_ = true; is_initialized_ = true;
FOR_EACH_OBSERVER(Observer, observers_, OnInitialized()); }
void ComponentExtensionIMEManager::NotifyInitialized() {
if (is_initialized_ && !was_initialization_notified_) {
FOR_EACH_OBSERVER(
Observer, observers_, OnImeComponentExtensionInitialized());
was_initialization_notified_ = true;
}
} }
bool ComponentExtensionIMEManager::IsInitialized() { bool ComponentExtensionIMEManager::IsInitialized() {
...@@ -203,6 +210,18 @@ input_method::InputMethodDescriptors ...@@ -203,6 +210,18 @@ input_method::InputMethodDescriptors
return result; return result;
} }
input_method::InputMethodDescriptors
ComponentExtensionIMEManager::GetXkbIMEAsInputMethodDescriptor() {
input_method::InputMethodDescriptors result;
const input_method::InputMethodDescriptors& descriptors =
GetAllIMEAsInputMethodDescriptor();
for (size_t i = 0; i < descriptors.size(); ++i) {
if (extension_ime_util::IsKeyboardLayoutExtension(descriptors[i].id()))
result.push_back(descriptors[i]);
}
return result;
}
void ComponentExtensionIMEManager::AddObserver(Observer* observer) { void ComponentExtensionIMEManager::AddObserver(Observer* observer) {
observers_.AddObserver(observer); observers_.AddObserver(observer);
} }
......
...@@ -66,7 +66,7 @@ class CHROMEOS_EXPORT ComponentExtensionIMEManager { ...@@ -66,7 +66,7 @@ class CHROMEOS_EXPORT ComponentExtensionIMEManager {
class Observer { class Observer {
public: public:
// Called when the initialization is done. // Called when the initialization is done.
virtual void OnInitialized() = 0; virtual void OnImeComponentExtensionInitialized() = 0;
}; };
ComponentExtensionIMEManager(); ComponentExtensionIMEManager();
...@@ -77,6 +77,9 @@ class CHROMEOS_EXPORT ComponentExtensionIMEManager { ...@@ -77,6 +77,9 @@ class CHROMEOS_EXPORT ComponentExtensionIMEManager {
// be called before using any other function. // be called before using any other function.
void Initialize(scoped_ptr<ComponentExtensionIMEManagerDelegate> delegate); void Initialize(scoped_ptr<ComponentExtensionIMEManagerDelegate> delegate);
// Notifies the observers for the component extension IMEs are initialized.
void NotifyInitialized();
// Returns true if the initialization is done, otherwise returns false. // Returns true if the initialization is done, otherwise returns false.
bool IsInitialized(); bool IsInitialized();
...@@ -114,6 +117,9 @@ class CHROMEOS_EXPORT ComponentExtensionIMEManager { ...@@ -114,6 +117,9 @@ class CHROMEOS_EXPORT ComponentExtensionIMEManager {
// Returns all IME as InputMethodDescriptors. // Returns all IME as InputMethodDescriptors.
input_method::InputMethodDescriptors GetAllIMEAsInputMethodDescriptor(); input_method::InputMethodDescriptors GetAllIMEAsInputMethodDescriptor();
// Returns all XKB keyboard IME as InputMethodDescriptors.
input_method::InputMethodDescriptors GetXkbIMEAsInputMethodDescriptor();
void AddObserver(Observer* observer); void AddObserver(Observer* observer);
void RemoveObserver(Observer* observer); void RemoveObserver(Observer* observer);
...@@ -135,6 +141,8 @@ class CHROMEOS_EXPORT ComponentExtensionIMEManager { ...@@ -135,6 +141,8 @@ class CHROMEOS_EXPORT ComponentExtensionIMEManager {
bool is_initialized_; bool is_initialized_;
bool was_initialization_notified_;
std::set<std::string> login_layout_set_; std::set<std::string> login_layout_set_;
DISALLOW_COPY_AND_ASSIGN(ComponentExtensionIMEManager); DISALLOW_COPY_AND_ASSIGN(ComponentExtensionIMEManager);
......
...@@ -122,7 +122,7 @@ class ComponentExtensionIMEManagerTest : ...@@ -122,7 +122,7 @@ class ComponentExtensionIMEManagerTest :
scoped_ptr<ComponentExtensionIMEManagerDelegate>( scoped_ptr<ComponentExtensionIMEManagerDelegate>(
mock_delegate_).Pass()); mock_delegate_).Pass());
EXPECT_TRUE(component_ext_mgr_->IsInitialized()); EXPECT_TRUE(component_ext_mgr_->IsInitialized());
component_ext_mgr_->NotifyInitialized();
} }
virtual void TearDown() { virtual void TearDown() {
...@@ -136,7 +136,7 @@ class ComponentExtensionIMEManagerTest : ...@@ -136,7 +136,7 @@ class ComponentExtensionIMEManagerTest :
std::vector<ComponentExtensionIME> ime_list_; std::vector<ComponentExtensionIME> ime_list_;
private: private:
virtual void OnInitialized() OVERRIDE { virtual void OnImeComponentExtensionInitialized() OVERRIDE {
++on_initialized_callcount_; ++on_initialized_callcount_;
} }
......
...@@ -66,9 +66,9 @@ class IMEBridgeImpl : public IMEBridge { ...@@ -66,9 +66,9 @@ class IMEBridgeImpl : public IMEBridge {
const std::string& engine_id) OVERRIDE { const std::string& engine_id) OVERRIDE {
std::map<std::string, IMEEngineHandlerInterface*>::const_iterator itor = std::map<std::string, IMEEngineHandlerInterface*>::const_iterator itor =
engine_handler_map_.find(engine_id); engine_handler_map_.find(engine_id);
// |engine_id| must be found unless it's empty, but if it's not found, fall // It is normal in that the engine is not found, because sometimes the
// back to NULL when non-debug build. // extension based xkb id may be provided but the xkb component extension
DCHECK(itor != engine_handler_map_.end() || engine_id.empty()); // is not installed, for example, in browser_tests.
if (itor == engine_handler_map_.end()) { if (itor == engine_handler_map_.end()) {
engine_handler_ = NULL; engine_handler_ = NULL;
return NULL; return NULL;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment