15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/input_method/input_method_manager_impl.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm> // std::find 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include <sstream> 1003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 11a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ash/ime/input_method_menu_item.h" 12a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ash/ime/input_method_menu_manager.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h" 14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/bind.h" 15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/location.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/metrics/histogram.h" 181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/metrics/sparse_histogram.h" 19424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "base/prefs/pref_service.h" 20f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "base/strings/string_split.h" 215e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/string_util.h" 225e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/stringprintf.h" 235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/sys_info.h" 24424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "chrome/browser/browser_process.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/input_method/candidate_window_controller.h" 26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/chromeos/input_method/component_extension_ime_manager_impl.h" 27a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/browser/chromeos/input_method/input_method_engine.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/language_preferences.h" 2903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "chrome/browser/chromeos/login/session/user_session_manager.h" 3003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "chrome/browser/chromeos/profiles/profile_helper.h" 31a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "chrome/browser/profiles/profile_manager.h" 32f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "chrome/common/pref_names.h" 33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chromeos/ime/component_extension_ime_manager.h" 34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chromeos/ime/extension_ime_util.h" 35a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "chromeos/ime/fake_ime_keyboard.h" 36a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "chromeos/ime/ime_keyboard.h" 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chromeos/ime/input_method_delegate.h" 3803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "components/user_manager/user_manager.h" 39ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "third_party/icu/source/common/unicode/uloc.h" 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/accelerators/accelerator.h" 411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "ui/keyboard/keyboard_controller.h" 421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "ui/keyboard/keyboard_util.h" 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace chromeos { 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace input_method { 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Contains(const std::vector<std::string>& container, 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& value) { 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return std::find(container.begin(), container.end(), value) != 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) container.end(); 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccienum InputMethodCategory { 561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci INPUT_METHOD_CATEGORY_UNKNOWN = 0, 571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci INPUT_METHOD_CATEGORY_XKB, // XKB input methods 581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci INPUT_METHOD_CATEGORY_ZH, // Chinese input methods 591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci INPUT_METHOD_CATEGORY_JA, // Japanese input methods 601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci INPUT_METHOD_CATEGORY_KO, // Korean input methods 611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci INPUT_METHOD_CATEGORY_M17N, // Multilingualization input methods 621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci INPUT_METHOD_CATEGORY_T13N, // Transliteration input methods 631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci INPUT_METHOD_CATEGORY_MAX 641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}; 651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciInputMethodCategory GetInputMethodCategory(const std::string& input_method_id, 671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci char* first_char = NULL) { 681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const std::string component_id = 691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci extension_ime_util::GetComponentIDByInputMethodID(input_method_id); 701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci InputMethodCategory category = INPUT_METHOD_CATEGORY_UNKNOWN; 711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci char ch = 0; 721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (StartsWithASCII(component_id, "xkb:", true)) { 731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ch = component_id[4]; 741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci category = INPUT_METHOD_CATEGORY_XKB; 751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } else if (StartsWithASCII(component_id, "zh-", true)) { 761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci size_t pos = component_id.find("-t-i0-"); 771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (pos > 0) 781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci pos += 6; 791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ch = component_id[pos]; 801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci category = INPUT_METHOD_CATEGORY_ZH; 811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } else if (StartsWithASCII(component_id, "nacl_mozc_", true)) { 821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ch = component_id[10]; 831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci category = INPUT_METHOD_CATEGORY_JA; 841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } else if (StartsWithASCII(component_id, "hangul_", true)) { 851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ch = component_id[7]; 861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci category = INPUT_METHOD_CATEGORY_KO; 871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } else if (StartsWithASCII(component_id, "vkd_", true)) { 881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ch = component_id[4]; 891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci category = INPUT_METHOD_CATEGORY_M17N; 901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } else if (component_id.find("-t-i0-") > 0) { 911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ch = component_id[0]; 921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci category = INPUT_METHOD_CATEGORY_T13N; 931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (first_char) 961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci *first_char = ch; 971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return category; 981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// ------------------------ InputMethodManagerImpl::StateImpl 103a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 10403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)InputMethodManagerImpl::StateImpl::StateImpl(InputMethodManagerImpl* manager, 10503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) Profile* profile) 10603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) : profile(profile), manager_(manager) { 107a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 108a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 10903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)InputMethodManagerImpl::StateImpl::~StateImpl() { 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void InputMethodManagerImpl::StateImpl::InitFrom(const StateImpl& other) { 11303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) previous_input_method = other.previous_input_method; 11403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) current_input_method = other.current_input_method; 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) active_input_method_ids = other.active_input_method_ids; 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) pending_input_method_id = other.pending_input_method_id; 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) enabled_extension_imes = other.enabled_extension_imes; 12103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) extra_input_methods = other.extra_input_methods; 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)bool InputMethodManagerImpl::StateImpl::IsActive() const { 12503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return manager_->state_.get() == this; 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)std::string InputMethodManagerImpl::StateImpl::Dump() const { 12903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) std::ostringstream os; 13003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 13103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) os << "################# " 13203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) << (profile ? profile->GetProfileName() : std::string("NULL")) 13303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) << " #################\n"; 13403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 13503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) os << "previous_input_method: '" 13603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) << previous_input_method.GetPreferredKeyboardLayout() << "'\n"; 13703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) os << "current_input_method: '" 13803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) << current_input_method.GetPreferredKeyboardLayout() << "'\n"; 13903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) os << "active_input_method_ids (size=" << active_input_method_ids.size() 14003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) << "):"; 14103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) for (size_t i = 0; i < active_input_method_ids.size(); ++i) { 14203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) os << " '" << active_input_method_ids[i] << "',"; 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) os << "\n"; 14503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) os << "enabled_extension_imes (size=" << enabled_extension_imes.size() 14603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) << "):"; 14703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) for (size_t i = 0; i < enabled_extension_imes.size(); ++i) { 14803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) os << " '" << enabled_extension_imes[i] << "'\n"; 14903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 15003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) os << "\n"; 15103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) os << "extra_input_methods (size=" << extra_input_methods.size() << "):"; 15203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) for (std::map<std::string, InputMethodDescriptor>::const_iterator it = 15303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) extra_input_methods.begin(); 15403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) it != extra_input_methods.end(); 15503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ++it) { 15603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) os << " '" << it->first << "' => '" << it->second.id() << "',\n"; 15703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 15803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) os << "pending_input_method_id: '" << pending_input_method_id << "'\n"; 15903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 16003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return os.str(); 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)scoped_refptr<InputMethodManager::State> 16403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)InputMethodManagerImpl::StateImpl::Clone() const { 16503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) scoped_refptr<StateImpl> new_state(new StateImpl(this->manager_, profile)); 16603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) new_state->InitFrom(*this); 16703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return scoped_refptr<InputMethodManager::State>(new_state.get()); 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_ptr<InputMethodDescriptors> 17103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)InputMethodManagerImpl::StateImpl::GetActiveInputMethods() const { 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<InputMethodDescriptors> result(new InputMethodDescriptors); 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Build the active input method descriptors from the active input 17403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // methods cache |active_input_method_ids|. 17503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) for (size_t i = 0; i < active_input_method_ids.size(); ++i) { 17603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const std::string& input_method_id = active_input_method_ids[i]; 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const InputMethodDescriptor* descriptor = 17803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) manager_->util_.GetInputMethodDescriptorFromId(input_method_id); 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (descriptor) { 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->push_back(*descriptor); 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::map<std::string, InputMethodDescriptor>::const_iterator ix = 18303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) extra_input_methods.find(input_method_id); 18403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (ix != extra_input_methods.end()) 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->push_back(ix->second); 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "Descriptor is not found for: " << input_method_id; 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result->empty()) { 19103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Initially |active_input_method_ids| is empty. browser_tests might take 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // this path. 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->push_back( 194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) InputMethodUtil::GetFallbackInputMethodDescriptor()); 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return result.Pass(); 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 199a3f7b4e666c476898878fa745f637129375cd889Ben Murdochconst std::vector<std::string>& 20003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)InputMethodManagerImpl::StateImpl::GetActiveInputMethodIds() const { 20103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return active_input_method_ids; 202a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch} 203a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 20403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)size_t InputMethodManagerImpl::StateImpl::GetNumActiveInputMethods() const { 20503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return active_input_method_ids.size(); 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)const InputMethodDescriptor* 20903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)InputMethodManagerImpl::StateImpl::GetInputMethodFromId( 2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& input_method_id) const { 21103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const InputMethodDescriptor* ime = 21203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) manager_->util_.GetInputMethodDescriptorFromId(input_method_id); 2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!ime) { 2145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::map<std::string, InputMethodDescriptor>::const_iterator ix = 21503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) extra_input_methods.find(input_method_id); 21603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (ix != extra_input_methods.end()) 2175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ime = &ix->second; 2185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return ime; 2205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 22203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void InputMethodManagerImpl::StateImpl::EnableLoginLayouts( 2235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& language_code, 2245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::vector<std::string>& initial_layouts) { 22503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (manager_->ui_session_ == STATE_TERMINATING) 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // First, hardware keyboard layout should be shown. 2295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::vector<std::string> candidates = 23003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) manager_->util_.GetHardwareLoginInputMethodIds(); 2315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 23203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Second, locale based input method should be shown. 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add input methods associated with the language. 2345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::vector<std::string> layouts_from_locale; 23503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) manager_->util_.GetInputMethodIdsFromLanguageCode( 23603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) language_code, kKeyboardLayoutsOnly, &layouts_from_locale); 2375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) candidates.insert(candidates.end(), layouts_from_locale.begin(), 2385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) layouts_from_locale.end()); 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<std::string> layouts; 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // First, add the initial input method ID, if it's requested, to 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // layouts, so it appears first on the list of active input 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // methods at the input language status menu. 2445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (size_t i = 0; i < initial_layouts.size(); ++i) { 24503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (manager_->util_.IsValidInputMethodId(initial_layouts[i])) { 24603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (manager_->IsLoginKeyboard(initial_layouts[i])) { 2475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) layouts.push_back(initial_layouts[i]); 2485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 2495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DVLOG(1) 2505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) << "EnableLoginLayouts: ignoring non-login initial keyboard layout:" 2515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) << initial_layouts[i]; 2525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else if (!initial_layouts[i].empty()) { 2545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DVLOG(1) << "EnableLoginLayouts: ignoring non-keyboard or invalid ID: " 2555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) << initial_layouts[i]; 2565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add candidates to layouts, while skipping duplicates. 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < candidates.size(); ++i) { 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& candidate = candidates[i]; 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Not efficient, but should be fine, as the two vectors are very 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // short (2-5 items). 26403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (!Contains(layouts, candidate) && manager_->IsLoginKeyboard(candidate)) 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) layouts.push_back(candidate); 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) manager_->MigrateInputMethods(&layouts); 26903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) active_input_method_ids.swap(layouts); 27003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 27103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (IsActive()) { 27203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Initialize candidate window controller and widgets such as 27303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // candidate window, infolist and mode indicator. Note, mode 27403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // indicator is used by only keyboard layout input methods. 27503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (active_input_method_ids.size() > 1) 27603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) manager_->MaybeInitializeCandidateWindowController(); 27703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 27803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // you can pass empty |initial_layout|. 27903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ChangeInputMethod(initial_layouts.empty() 28003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ? std::string() 28103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) : extension_ime_util::GetInputMethodIDByEngineID( 28203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) initial_layouts[0]), 28303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) false); 28403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 28503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 286a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 28703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void InputMethodManagerImpl::StateImpl::EnableLockScreenLayouts() { 28803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) std::set<std::string> added_ids; 289a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 29003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const std::vector<std::string>& hardware_keyboard_ids = 29103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) manager_->util_.GetHardwareLoginInputMethodIds(); 29203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 29303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) std::vector<std::string> new_active_input_method_ids; 29403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) for (size_t i = 0; i < active_input_method_ids.size(); ++i) { 29503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const std::string& input_method_id = active_input_method_ids[i]; 29603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Skip if it's not a keyboard layout. Drop input methods including 29703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // extension ones. 29803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (!manager_->IsLoginKeyboard(input_method_id) || 29903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) added_ids.count(input_method_id)) { 30003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) continue; 30103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 30203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) new_active_input_method_ids.push_back(input_method_id); 30303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) added_ids.insert(input_method_id); 30403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 30503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 30603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // We'll add the hardware keyboard if it's not included in 30703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // |active_input_method_ids| so that the user can always use the hardware 30803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // keyboard on the screen locker. 30903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) for (size_t i = 0; i < hardware_keyboard_ids.size(); ++i) { 31003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (added_ids.count(hardware_keyboard_ids[i])) 31103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) continue; 31203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) new_active_input_method_ids.push_back(hardware_keyboard_ids[i]); 31303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) added_ids.insert(hardware_keyboard_ids[i]); 31403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 31503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 31603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) active_input_method_ids.swap(new_active_input_method_ids); 31703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 31803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Re-check current_input_method. 31903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ChangeInputMethod(current_input_method.id(), false); 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 322a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch// Adds new input method to given list. 32303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)bool InputMethodManagerImpl::StateImpl::EnableInputMethodImpl( 324a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch const std::string& input_method_id, 325f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) std::vector<std::string>* new_active_input_method_ids) const { 326f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(new_active_input_method_ids); 32703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (!manager_->util_.IsValidInputMethodId(input_method_id)) { 328a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch DVLOG(1) << "EnableInputMethod: Invalid ID: " << input_method_id; 329a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch return false; 330a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch } 331a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 332f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!Contains(*new_active_input_method_ids, input_method_id)) 333f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) new_active_input_method_ids->push_back(input_method_id); 334a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 335a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch return true; 336a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch} 337a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 33803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)bool InputMethodManagerImpl::StateImpl::EnableInputMethod( 339a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch const std::string& input_method_id) { 34003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (!EnableInputMethodImpl(input_method_id, &active_input_method_ids)) 341a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch return false; 342a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 34303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) manager_->ReconfigureIMFramework(this); 344a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch return true; 345a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch} 346a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 34703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)bool InputMethodManagerImpl::StateImpl::ReplaceEnabledInputMethods( 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<std::string>& new_active_input_method_ids) { 34903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (manager_->ui_session_ == STATE_TERMINATING) 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Filter unknown or obsolete IDs. 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<std::string> new_active_input_method_ids_filtered; 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch for (size_t i = 0; i < new_active_input_method_ids.size(); ++i) 356a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch EnableInputMethodImpl(new_active_input_method_ids[i], 357f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) &new_active_input_method_ids_filtered); 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (new_active_input_method_ids_filtered.empty()) { 3605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DVLOG(1) << "ReplaceEnabledInputMethods: No valid input method ID"; 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Copy extension IDs to |new_active_input_method_ids_filtered|. We have to 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // keep relative order of the extension input method IDs. 36603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) for (size_t i = 0; i < active_input_method_ids.size(); ++i) { 36703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const std::string& input_method_id = active_input_method_ids[i]; 368c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (extension_ime_util::IsExtensionIME(input_method_id)) 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new_active_input_method_ids_filtered.push_back(input_method_id); 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 37103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) active_input_method_ids.swap(new_active_input_method_ids_filtered); 37203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) manager_->MigrateInputMethods(&active_input_method_ids); 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 37403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) manager_->ReconfigureIMFramework(this); 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 37603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // If |current_input_method| is no longer in |active_input_method_ids|, 37703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // ChangeInputMethod() picks the first one in |active_input_method_ids|. 37803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ChangeInputMethod(current_input_method.id(), false); 3791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Record histogram for active input method count. 3811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci UMA_HISTOGRAM_COUNTS("InputMethod.ActiveCount", 3821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci active_input_method_ids.size()); 3831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 38703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void InputMethodManagerImpl::StateImpl::ChangeInputMethod( 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& input_method_id, 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool show_message) { 39003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (manager_->ui_session_ == STATE_TERMINATING) 39103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return; 3925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 39303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) bool notify_menu = false; 39403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // For 3rd party IME, when the user just logged in, SetEnabledExtensionImes 39503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // happens after activating the 3rd party IME. 39603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // So here to record the 3rd party IME to be activated, and activate it 39703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // when SetEnabledExtensionImes happens later. 39803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (MethodAwaitsExtensionLoad(input_method_id)) 39903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) pending_input_method_id = input_method_id; 40003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 40103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Always lookup input method, even if it is the same as 40203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // |current_input_method| because If it is no longer in 40303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // |active_input_method_ids|, pick the first one in 40403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // |active_input_method_ids|. 40503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const InputMethodDescriptor* descriptor = 40603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) manager_->LookupInputMethod(input_method_id, this); 40703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (descriptor->id() != current_input_method.id()) { 40803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) previous_input_method = current_input_method; 40903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) current_input_method = *descriptor; 41003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) notify_menu = true; 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 41303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Always change input method even if it is the same. 41403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // TODO(komatsu): Revisit if this is neccessary. 41503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (IsActive()) 41603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) manager_->ChangeInputMethodInternal(*descriptor, show_message, notify_menu); 4171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci manager_->RecordInputMethodUsage(current_input_method.id()); 418c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 419c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 42003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)bool InputMethodManagerImpl::StateImpl::MethodAwaitsExtensionLoad( 42103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const std::string& input_method_id) const { 42203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // For 3rd party IME, when the user just logged in, SetEnabledExtensionImes 42303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // happens after activating the 3rd party IME. 42403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // So here to record the 3rd party IME to be activated, and activate it 42503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // when SetEnabledExtensionImes happens later. 42603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return !InputMethodIsActivated(input_method_id) && 42703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) extension_ime_util::IsExtensionIME(input_method_id); 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 43003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void InputMethodManagerImpl::StateImpl::AddInputMethodExtension( 4315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const std::string& extension_id, 4325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const InputMethodDescriptors& descriptors, 433a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) InputMethodEngineInterface* engine) { 43403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (manager_->ui_session_ == STATE_TERMINATING) 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 437116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK(engine); 438116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 43903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) manager_->engine_map_[extension_id] = engine; 4405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 4415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) bool contain = false; 4425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for (size_t i = 0; i < descriptors.size(); i++) { 4435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const InputMethodDescriptor& descriptor = descriptors[i]; 4445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const std::string& id = descriptor.id(); 44503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) extra_input_methods[id] = descriptor; 44603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (Contains(enabled_extension_imes, id)) { 44703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (!Contains(active_input_method_ids, id)) { 44803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) active_input_method_ids.push_back(id); 4495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } else { 4505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DVLOG(1) << "AddInputMethodExtension: already added: " << id << ", " 4515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) << descriptor.name(); 4525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 4535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) contain = true; 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 45703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (IsActive()) { 45803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (extension_id == extension_ime_util::GetExtensionIDFromInputMethodID( 45903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) current_input_method.id())) { 46003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) IMEBridge::Get()->SetCurrentEngineHandler(engine); 46103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) engine->Enable(extension_ime_util::GetComponentIDByInputMethodID( 46203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) current_input_method.id())); 46303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 46403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 46503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Ensure that the input method daemon is running. 46603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (contain) 46703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) manager_->MaybeInitializeCandidateWindowController(); 46803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 47103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void InputMethodManagerImpl::StateImpl::RemoveInputMethodExtension( 4725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const std::string& extension_id) { 4735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Remove the active input methods with |extension_id|. 4745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) std::vector<std::string> new_active_input_method_ids; 47503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) for (size_t i = 0; i < active_input_method_ids.size(); ++i) { 4765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (extension_id != extension_ime_util::GetExtensionIDFromInputMethodID( 47703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) active_input_method_ids[i])) 47803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) new_active_input_method_ids.push_back(active_input_method_ids[i]); 4795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 48003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) active_input_method_ids.swap(new_active_input_method_ids); 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Remove the extra input methods with |extension_id|. 4835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) std::map<std::string, InputMethodDescriptor> new_extra_input_methods; 4845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for (std::map<std::string, InputMethodDescriptor>::iterator i = 48503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) extra_input_methods.begin(); 48603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) i != extra_input_methods.end(); 4875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ++i) { 4885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (extension_id != 4895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) extension_ime_util::GetExtensionIDFromInputMethodID(i->first)) 4905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) new_extra_input_methods[i->first] = i->second; 4915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 49203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) extra_input_methods.swap(new_extra_input_methods); 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 49403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (IsActive()) { 49503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (IMEBridge::Get()->GetCurrentEngineHandler() == 49603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) manager_->engine_map_[extension_id]) { 49703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) IMEBridge::Get()->SetCurrentEngineHandler(NULL); 49803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 49903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) manager_->engine_map_.erase(extension_id); 500116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 50103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 50203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // If |current_input_method| is no longer in |active_input_method_ids|, 50303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // switch to the first one in |active_input_method_ids|. 50403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ChangeInputMethod(current_input_method.id(), false); 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 50703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void InputMethodManagerImpl::StateImpl::GetInputMethodExtensions( 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InputMethodDescriptors* result) { 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Build the extension input method descriptors from the extra input 51003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // methods cache |extra_input_methods|. 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::map<std::string, InputMethodDescriptor>::iterator iter; 51203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) for (iter = extra_input_methods.begin(); iter != extra_input_methods.end(); 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++iter) { 514c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (extension_ime_util::IsExtensionIME(iter->first)) 515c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) result->push_back(iter->second); 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 51903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void InputMethodManagerImpl::StateImpl::SetEnabledExtensionImes( 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<std::string>* ids) { 52103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) enabled_extension_imes.clear(); 52203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) enabled_extension_imes.insert( 52303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) enabled_extension_imes.end(), ids->begin(), ids->end()); 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool active_imes_changed = false; 5256e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) bool switch_to_pending = false; 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::map<std::string, InputMethodDescriptor>::iterator extra_iter = 52803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) extra_input_methods.begin(); 52903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) extra_iter != extra_input_methods.end(); 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++extra_iter) { 53103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (extension_ime_util::IsComponentExtensionIME(extra_iter->first)) 532c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) continue; // Do not filter component extension. 5336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 53403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (pending_input_method_id == extra_iter->first) 5356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) switch_to_pending = true; 5366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 53703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) std::vector<std::string>::iterator active_iter = 53803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) std::find(active_input_method_ids.begin(), 53903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) active_input_method_ids.end(), 54003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) extra_iter->first); 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 54203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) bool active = active_iter != active_input_method_ids.end(); 54303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) bool enabled = Contains(enabled_extension_imes, extra_iter->first); 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 545b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (active && !enabled) 54603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) active_input_method_ids.erase(active_iter); 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 548b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!active && enabled) 54903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) active_input_method_ids.push_back(extra_iter->first); 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 551b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (active == !enabled) 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) active_imes_changed = true; 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (IsActive() && active_imes_changed) { 55603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) manager_->MaybeInitializeCandidateWindowController(); 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5586e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (switch_to_pending) { 55903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ChangeInputMethod(pending_input_method_id, false); 56003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) pending_input_method_id.clear(); 5616e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } else { 5626e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // If |current_input_method| is no longer in |active_input_method_ids_|, 5636e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // switch to the first one in |active_input_method_ids_|. 56403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ChangeInputMethod(current_input_method.id(), false); 5656e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 56903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void InputMethodManagerImpl::StateImpl::SetInputMethodLoginDefaultFromVPD( 57003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const std::string& locale, 57103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const std::string& oem_layout) { 572f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) std::string layout; 573f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (!oem_layout.empty()) { 574f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // If the OEM layout information is provided, use it. 575f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) layout = oem_layout; 576f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } else { 577f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Otherwise, determine the hardware keyboard from the locale. 578f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) std::vector<std::string> input_method_ids; 57903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (manager_->util_.GetInputMethodIdsFromLanguageCode( 58003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) locale, 58103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) chromeos::input_method::kKeyboardLayoutsOnly, 58203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) &input_method_ids)) { 583f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // The output list |input_method_ids| is sorted by popularity, hence 584f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // input_method_ids[0] now contains the most popular keyboard layout 585f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // for the given locale. 586f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DCHECK_GE(input_method_ids.size(), 1U); 587f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) layout = input_method_ids[0]; 588f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 589f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 590f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 591f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (layout.empty()) 592f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return; 593f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 594f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) std::vector<std::string> layouts; 595f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) base::SplitString(layout, ',', &layouts); 59603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) manager_->MigrateInputMethods(&layouts); 597f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 598f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) PrefService* prefs = g_browser_process->local_state(); 599f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) prefs->SetString(prefs::kHardwareKeyboardLayout, JoinString(layouts, ",")); 600f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 601f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // This asks the file thread to save the prefs (i.e. doesn't block). 602f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // The latest values of Local State reside in memory so we can safely 603f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // get the value of kHardwareKeyboardLayout even if the data is not 604f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // yet saved to disk. 605f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) prefs->CommitPendingWrite(); 606f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 60703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) manager_->util_.UpdateHardwareLayoutCache(); 608f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 609f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) EnableLoginLayouts(locale, layouts); 61003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) manager_->LoadNecessaryComponentExtensions(this); 611f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 612f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 61303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void InputMethodManagerImpl::StateImpl::SetInputMethodLoginDefault() { 614424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Set up keyboards. For example, when |locale| is "en-US", enable US qwerty 615424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // and US dvorak keyboard layouts. 616424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (g_browser_process && g_browser_process->local_state()) { 617424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const std::string locale = g_browser_process->GetApplicationLocale(); 618424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // If the preferred keyboard for the login screen has been saved, use it. 619424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) PrefService* prefs = g_browser_process->local_state(); 620424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) std::string initial_input_method_id = 621424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) prefs->GetString(chromeos::language_prefs::kPreferredKeyboardLayout); 6225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::vector<std::string> input_methods_to_be_enabled; 623424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (initial_input_method_id.empty()) { 624424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // If kPreferredKeyboardLayout is not specified, use the hardware layout. 62503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) input_methods_to_be_enabled = 62603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) manager_->util_.GetHardwareLoginInputMethodIds(); 6275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 6285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) input_methods_to_be_enabled.push_back(initial_input_method_id); 629424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 6305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EnableLoginLayouts(locale, input_methods_to_be_enabled); 63103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) manager_->LoadNecessaryComponentExtensions(this); 632424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 633424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 634424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 63503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)bool InputMethodManagerImpl::StateImpl::SwitchToNextInputMethod() { 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Sanity checks. 63703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (active_input_method_ids.empty()) { 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "active input method is empty"; 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 641a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 64203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (current_input_method.id().empty()) { 64303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) DVLOG(1) << "current_input_method is unknown"; 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 647a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) // Do not consume key event if there is only one input method is enabled. 648a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) // Ctrl+Space or Alt+Shift may be used by other application. 64903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (active_input_method_ids.size() == 1) 650a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) return false; 651a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Find the next input method and switch to it. 65303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) SwitchToNextInputMethodInternal(active_input_method_ids, 65403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) current_input_method.id()); 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 65803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)bool InputMethodManagerImpl::StateImpl::SwitchToPreviousInputMethod( 659a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch const ui::Accelerator& accelerator) { 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Sanity check. 66103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (active_input_method_ids.empty()) { 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "active input method is empty"; 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 666a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) // Do not consume key event if there is only one input method is enabled. 667a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) // Ctrl+Space or Alt+Shift may be used by other application. 66803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (active_input_method_ids.size() == 1) 669a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) return false; 670a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 671a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch if (accelerator.type() == ui::ET_KEY_RELEASED) 672a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch return true; 673a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 67403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (previous_input_method.id().empty() || 67503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) previous_input_method.id() == current_input_method.id()) { 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SwitchToNextInputMethod(); 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<std::string>::const_iterator iter = 68003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) std::find(active_input_method_ids.begin(), 68103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) active_input_method_ids.end(), 68203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) previous_input_method.id()); 68303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (iter == active_input_method_ids.end()) { 68403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // previous_input_method is not supported. 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SwitchToNextInputMethod(); 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 68703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ChangeInputMethod(*iter, true); 68803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 69203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)bool InputMethodManagerImpl::StateImpl::SwitchInputMethod( 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ui::Accelerator& accelerator) { 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Sanity check. 69503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (active_input_method_ids.empty()) { 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "active input method is empty"; 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Get the list of input method ids for the |accelerator|. For example, get 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // { "mozc-hangul", "xkb:kr:kr104:kor" } for ui::VKEY_DBE_SBCSCHAR. 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<std::string> input_method_ids_to_switch; 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (accelerator.key_code()) { 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ui::VKEY_CONVERT: // Henkan key on JP106 keyboard 70546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) input_method_ids_to_switch.push_back( 70646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) extension_ime_util::GetInputMethodIDByEngineID("nacl_mozc_jp")); 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ui::VKEY_NONCONVERT: // Muhenkan key on JP106 keyboard 70946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) input_method_ids_to_switch.push_back( 71046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) extension_ime_util::GetInputMethodIDByEngineID("xkb:jp::jpn")); 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ui::VKEY_DBE_SBCSCHAR: // ZenkakuHankaku key on JP106 keyboard 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ui::VKEY_DBE_DBCSCHAR: 71446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) input_method_ids_to_switch.push_back( 71546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) extension_ime_util::GetInputMethodIDByEngineID("nacl_mozc_jp")); 71646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) input_method_ids_to_switch.push_back( 71746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) extension_ime_util::GetInputMethodIDByEngineID("xkb:jp::jpn")); 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (input_method_ids_to_switch.empty()) { 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "Unexpected VKEY: " << accelerator.key_code(); 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Obtain the intersection of input_method_ids_to_switch and 72903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // active_input_method_ids. The order of IDs in active_input_method_ids is 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // preserved. 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<std::string> ids; 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < input_method_ids_to_switch.size(); ++i) { 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& id = input_method_ids_to_switch[i]; 73403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (Contains(active_input_method_ids, id)) 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ids.push_back(id); 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ids.empty()) { 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // No input method for the accelerator is active. For example, we should 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // just ignore VKEY_HANGUL when mozc-hangul is not active. 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 74303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) SwitchToNextInputMethodInternal(ids, current_input_method.id()); 7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; // consume the accelerator. 7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 74703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void InputMethodManagerImpl::StateImpl::SwitchToNextInputMethodInternal( 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<std::string>& input_method_ids, 74903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const std::string& current_input_methodid) { 75003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) std::vector<std::string>::const_iterator iter = std::find( 75103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) input_method_ids.begin(), input_method_ids.end(), current_input_methodid); 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (iter != input_method_ids.end()) 7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++iter; 7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (iter == input_method_ids.end()) 7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iter = input_method_ids.begin(); 75603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ChangeInputMethod(*iter, true); 7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)InputMethodDescriptor InputMethodManagerImpl::StateImpl::GetCurrentInputMethod() 76003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const { 76103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (current_input_method.id().empty()) 762c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return InputMethodUtil::GetFallbackInputMethodDescriptor(); 7635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 76403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return current_input_method; 76503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 76603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 76703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)bool InputMethodManagerImpl::StateImpl::InputMethodIsActivated( 76803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const std::string& input_method_id) const { 76903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return Contains(active_input_method_ids, input_method_id); 77003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 77103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 77203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// ------------------------ InputMethodManagerImpl 77303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)bool InputMethodManagerImpl::IsLoginKeyboard( 77403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const std::string& layout) const { 77503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return util_.IsLoginKeyboard(layout); 77603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 77703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 77803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)bool InputMethodManagerImpl::MigrateInputMethods( 77903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) std::vector<std::string>* input_method_ids) { 78003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return util_.MigrateInputMethods(input_method_ids); 78103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 78203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 78303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// Starts or stops the system input method framework as needed. 78403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void InputMethodManagerImpl::ReconfigureIMFramework( 78503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) InputMethodManagerImpl::StateImpl* state) { 78603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) LoadNecessaryComponentExtensions(state); 78703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 78803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Initialize candidate window controller and widgets such as 78903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // candidate window, infolist and mode indicator. Note, mode 79003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // indicator is used by only keyboard layout input methods. 79103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (state_.get() == state) 79203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) MaybeInitializeCandidateWindowController(); 79303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 79403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 79503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void InputMethodManagerImpl::SetState( 79603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) scoped_refptr<InputMethodManager::State> state) { 7971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(state.get()); 79803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) InputMethodManagerImpl::StateImpl* new_impl_state = 79903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) static_cast<InputMethodManagerImpl::StateImpl*>(state.get()); 80003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const bool need_update_current_input_method = 8011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci (state_.get() 8021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ? state_->current_input_method.id() != 8031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci new_impl_state->current_input_method.id() 8041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci : true); 80503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) state_ = new_impl_state; 80603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 8071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (state_.get() && state_->active_input_method_ids.size()) { 80803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Initialize candidate window controller and widgets such as 80903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // candidate window, infolist and mode indicator. Note, mode 81003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // indicator is used by only keyboard layout input methods. 81103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) MaybeInitializeCandidateWindowController(); 81203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 81303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (need_update_current_input_method) { 81403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ChangeInputMethodInternal(state_->current_input_method, 81503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) false /* show_message */, 81603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) true /* notify_menu */); 81703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } else { 81803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Update input method indicators (e.g. "US", "DV") in Chrome windows. 81903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) FOR_EACH_OBSERVER(InputMethodManager::Observer, 82003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) observers_, 82103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) InputMethodChanged(this, false /* show_message */)); 82203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 82303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 82403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 82503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 82603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)scoped_refptr<InputMethodManager::State> 82703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)InputMethodManagerImpl::GetActiveIMEState() { 82803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return scoped_refptr<InputMethodManager::State>(state_.get()); 82903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 83003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 83103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)InputMethodManagerImpl::InputMethodManagerImpl( 83203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) scoped_ptr<InputMethodDelegate> delegate, 83303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) bool enable_extension_loading) 83403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) : delegate_(delegate.Pass()), 83503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ui_session_(STATE_LOGIN_SCREEN), 83603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) state_(NULL), 83703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) util_(delegate_.get()), 83803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) component_extension_ime_manager_(new ComponentExtensionIMEManager()), 83903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) enable_extension_loading_(enable_extension_loading) { 84003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (base::SysInfo::IsRunningOnChromeOS()) 84103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) keyboard_.reset(ImeKeyboard::Create()); 84203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) else 84303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) keyboard_.reset(new FakeImeKeyboard()); 84403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 84503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Initializes the system IME list. 84603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) scoped_ptr<ComponentExtensionIMEManagerDelegate> comp_delegate( 84703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) new ComponentExtensionIMEManagerImpl()); 84803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) component_extension_ime_manager_->Initialize(comp_delegate.Pass()); 8491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const InputMethodDescriptors& descriptors = 8501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci component_extension_ime_manager_->GetAllIMEAsInputMethodDescriptor(); 8511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci util_.ResetInputMethods(descriptors); 8521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 8531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Initializes the stat id map. 8541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci std::map<int, std::vector<std::string> > buckets; 8551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci for (InputMethodDescriptors::const_iterator it = descriptors.begin(); 8561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci it != descriptors.end(); ++it) { 8571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci char first_char; 8581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int cat_id = static_cast<int>( 8591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci GetInputMethodCategory(it->id(), &first_char)); 8601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int key = cat_id * 1000 + first_char; 8611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci buckets[key].push_back(it->id()); 8621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 8631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci for (std::map<int, std::vector<std::string>>::iterator i = 8641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci buckets.begin(); i != buckets.end(); ++i) { 8651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci std::sort(i->second.begin(), i->second.end()); 8661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci for (size_t j = 0; j < i->second.size() && j < 100; ++j) { 8671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int key = i->first * 100 + j; 8681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci stat_id_map_[i->second[j]] = key; 8691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 8701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 87103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 87203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 87303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)InputMethodManagerImpl::~InputMethodManagerImpl() { 87403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (candidate_window_controller_.get()) 87503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) candidate_window_controller_->RemoveObserver(this); 87603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 87703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 8781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid InputMethodManagerImpl::RecordInputMethodUsage( 8791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci std::string input_method_id) { 8801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci UMA_HISTOGRAM_ENUMERATION("InputMethod.Category", 8811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci GetInputMethodCategory(input_method_id), 8821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci INPUT_METHOD_CATEGORY_MAX); 8831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci UMA_HISTOGRAM_SPARSE_SLOWLY("InputMethod.ID", 8841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci stat_id_map_[input_method_id]); 8851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 8861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 88703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void InputMethodManagerImpl::AddObserver( 88803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) InputMethodManager::Observer* observer) { 88903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) observers_.AddObserver(observer); 89003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 89103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 89203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void InputMethodManagerImpl::AddCandidateWindowObserver( 89303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) InputMethodManager::CandidateWindowObserver* observer) { 89403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) candidate_window_observers_.AddObserver(observer); 89503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 89603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 89703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void InputMethodManagerImpl::RemoveObserver( 89803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) InputMethodManager::Observer* observer) { 89903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) observers_.RemoveObserver(observer); 90003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 90103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 90203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void InputMethodManagerImpl::RemoveCandidateWindowObserver( 90303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) InputMethodManager::CandidateWindowObserver* observer) { 90403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) candidate_window_observers_.RemoveObserver(observer); 90503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 90603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 90703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)InputMethodManager::UISessionState InputMethodManagerImpl::GetUISessionState() { 90803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return ui_session_; 90903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 91003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 91103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void InputMethodManagerImpl::SetUISessionState(UISessionState new_ui_session) { 91203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ui_session_ = new_ui_session; 91303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) switch (ui_session_) { 91403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) case STATE_LOGIN_SCREEN: 91503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) break; 91603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) case STATE_BROWSER_SCREEN: 91703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) break; 91803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) case STATE_LOCK_SCREEN: 91903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) break; 92003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) case STATE_TERMINATING: { 92103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (candidate_window_controller_.get()) 92203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) candidate_window_controller_.reset(); 92303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) break; 92403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 92503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 92603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 92703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 92803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)scoped_ptr<InputMethodDescriptors> 92903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)InputMethodManagerImpl::GetSupportedInputMethods() const { 93003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return scoped_ptr<InputMethodDescriptors>(new InputMethodDescriptors).Pass(); 93103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 93203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 93303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)const InputMethodDescriptor* InputMethodManagerImpl::LookupInputMethod( 93403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const std::string& input_method_id, 93503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) InputMethodManagerImpl::StateImpl* state) { 93603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) DCHECK(state); 93703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 93803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) std::string input_method_id_to_switch = input_method_id; 93903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 94003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Sanity check 94103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (!state->InputMethodIsActivated(input_method_id)) { 94203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) scoped_ptr<InputMethodDescriptors> input_methods( 94303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) state->GetActiveInputMethods()); 94403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) DCHECK(!input_methods->empty()); 94503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) input_method_id_to_switch = input_methods->at(0).id(); 94603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (!input_method_id.empty()) { 94703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) DVLOG(1) << "Can't change the current input method to " 94803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) << input_method_id << " since the engine is not enabled. " 94903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) << "Switch to " << input_method_id_to_switch << " instead."; 95003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 95103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 95203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 95303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const InputMethodDescriptor* descriptor = NULL; 95403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (extension_ime_util::IsExtensionIME(input_method_id_to_switch)) { 95503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) DCHECK(state->extra_input_methods.find(input_method_id_to_switch) != 95603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) state->extra_input_methods.end()); 95703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) descriptor = &(state->extra_input_methods[input_method_id_to_switch]); 95803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } else { 95903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) descriptor = 96003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) util_.GetInputMethodDescriptorFromId(input_method_id_to_switch); 96103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (!descriptor) 96203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) LOG(ERROR) << "Unknown input method id: " << input_method_id_to_switch; 96303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 96403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) DCHECK(descriptor); 96503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return descriptor; 96603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 96703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 96803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void InputMethodManagerImpl::ChangeInputMethodInternal( 96903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const InputMethodDescriptor& descriptor, 97003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) bool show_message, 97103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) bool notify_menu) { 97203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // No need to switch input method when terminating. 97303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (ui_session_ == STATE_TERMINATING) 97403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return; 97503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 97603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (candidate_window_controller_.get()) 97703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) candidate_window_controller_->Hide(); 97803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 97903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (notify_menu) { 98003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Clear property list. Property list would be updated by 98103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // extension IMEs via InputMethodEngine::(Set|Update)MenuItems. 98203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // If the current input method is a keyboard layout, empty 98303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // properties are sufficient. 98403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const ash::ime::InputMethodMenuItemList empty_menu_item_list; 98503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ash::ime::InputMethodMenuManager* input_method_menu_manager = 98603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ash::ime::InputMethodMenuManager::GetInstance(); 98703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) input_method_menu_manager->SetCurrentInputMethodMenuItemList( 98803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) empty_menu_item_list); 98903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 99003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 99103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Disable the current engine handler. 99203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) IMEEngineHandlerInterface* engine = 99303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) IMEBridge::Get()->GetCurrentEngineHandler(); 99403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (engine) 99503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) engine->Disable(); 99603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 99703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Configure the next engine handler. 99803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // This must be after |current_input_method| has been set to new input 99903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // method, because engine's Enable() method needs to access it. 100003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const std::string& extension_id = 100103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) extension_ime_util::GetExtensionIDFromInputMethodID(descriptor.id()); 100203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const std::string& component_id = 100303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) extension_ime_util::GetComponentIDByInputMethodID(descriptor.id()); 100403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) engine = engine_map_[extension_id]; 100503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 100603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) IMEBridge::Get()->SetCurrentEngineHandler(engine); 100703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 10081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (engine) { 100903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) engine->Enable(component_id); 10101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } else { 10111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // If no engine to enable, cancel the virtual keyboard url override so that 10121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // it can use the fallback system virtual keyboard UI. 10131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci keyboard::SetOverrideContentUrl(GURL()); 10141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci keyboard::KeyboardController* keyboard_controller = 10151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci keyboard::KeyboardController::GetInstance(); 10161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (keyboard_controller) 10171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci keyboard_controller->Reload(); 10181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 101903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 102003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Change the keyboard layout to a preferred layout for the input method. 102103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (!keyboard_->SetCurrentKeyboardLayoutByName( 102203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) descriptor.GetPreferredKeyboardLayout())) { 102303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) LOG(ERROR) << "Failed to change keyboard layout to " 102403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) << descriptor.GetPreferredKeyboardLayout(); 102503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 102603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 102703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Update input method indicators (e.g. "US", "DV") in Chrome windows. 102803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) FOR_EACH_OBSERVER(InputMethodManager::Observer, 102903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) observers_, 103003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) InputMethodChanged(this, show_message)); 103103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 103203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 103303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void InputMethodManagerImpl::LoadNecessaryComponentExtensions( 103403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) InputMethodManagerImpl::StateImpl* state) { 103503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Load component extensions but also update |active_input_method_ids| as 103603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // some component extension IMEs may have been removed from the Chrome OS 103703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // image. If specified component extension IME no longer exists, falling back 103803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // to an existing IME. 103903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) DCHECK(state); 104003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) std::vector<std::string> unfiltered_input_method_ids; 104103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) unfiltered_input_method_ids.swap(state->active_input_method_ids); 104203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) for (size_t i = 0; i < unfiltered_input_method_ids.size(); ++i) { 104303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (!extension_ime_util::IsComponentExtensionIME( 104403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) unfiltered_input_method_ids[i])) { 104503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Legacy IMEs or xkb layouts are alwayes active. 104603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) state->active_input_method_ids.push_back(unfiltered_input_method_ids[i]); 104703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } else if (component_extension_ime_manager_->IsWhitelisted( 104803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) unfiltered_input_method_ids[i])) { 104903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (enable_extension_loading_) { 105003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) component_extension_ime_manager_->LoadComponentExtensionIME( 105103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) state->profile, unfiltered_input_method_ids[i]); 105203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 105303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 105403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) state->active_input_method_ids.push_back(unfiltered_input_method_ids[i]); 105503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 105603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 105703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 105803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 105903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void InputMethodManagerImpl::ActivateInputMethodMenuItem( 106003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const std::string& key) { 106103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) DCHECK(!key.empty()); 106203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 106303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (ash::ime::InputMethodMenuManager::GetInstance()-> 106403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) HasInputMethodMenuItemForKey(key)) { 106503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) IMEEngineHandlerInterface* engine = 106603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) IMEBridge::Get()->GetCurrentEngineHandler(); 106703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (engine) 106803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) engine->PropertyActivate(key); 106903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return; 107003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 107103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 107203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) DVLOG(1) << "ActivateInputMethodMenuItem: unknown key: " << key; 10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1075effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochbool InputMethodManagerImpl::IsISOLevel5ShiftUsedByCurrentInputMethod() const { 1076a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return keyboard_->IsISOLevel5ShiftAvailable(); 1077effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 1078effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 1079effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochbool InputMethodManagerImpl::IsAltGrUsedByCurrentInputMethod() const { 1080a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return keyboard_->IsAltGrAvailable(); 1081effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 1082effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 1083a02191e04bc25c4935f804f2c080ae28663d096dBen MurdochImeKeyboard* InputMethodManagerImpl::GetImeKeyboard() { 1084a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return keyboard_.get(); 10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)InputMethodUtil* InputMethodManagerImpl::GetInputMethodUtil() { 10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return &util_; 10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1091c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)ComponentExtensionIMEManager* 1092c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) InputMethodManagerImpl::GetComponentExtensionIMEManager() { 1093c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return component_extension_ime_manager_.get(); 1094c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 1095c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 109603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)scoped_refptr<InputMethodManager::State> InputMethodManagerImpl::CreateNewState( 109703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) Profile* profile) { 109803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return scoped_refptr<InputMethodManager::State>(new StateImpl(this, profile)); 109903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 110003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InputMethodManagerImpl::SetCandidateWindowControllerForTesting( 11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CandidateWindowController* candidate_window_controller) { 11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) candidate_window_controller_.reset(candidate_window_controller); 11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) candidate_window_controller_->AddObserver(this); 11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1107a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid InputMethodManagerImpl::SetImeKeyboardForTesting(ImeKeyboard* keyboard) { 1108a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch keyboard_.reset(keyboard); 11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void InputMethodManagerImpl::InitializeComponentExtensionForTesting( 1112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<ComponentExtensionIMEManagerDelegate> delegate) { 11135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) component_extension_ime_manager_->Initialize(delegate.Pass()); 11145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) util_.ResetInputMethods( 11155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) component_extension_ime_manager_->GetAllIMEAsInputMethodDescriptor()); 1116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 1117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1118a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void InputMethodManagerImpl::CandidateClicked(int index) { 11195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) IMEEngineHandlerInterface* engine = 11205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) IMEBridge::Get()->GetCurrentEngineHandler(); 1121a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (engine) 1122a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) engine->CandidateClicked(index); 1123a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 1124a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InputMethodManagerImpl::CandidateWindowOpened() { 11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FOR_EACH_OBSERVER(InputMethodManager::CandidateWindowObserver, 11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) candidate_window_observers_, 11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CandidateWindowOpened(this)); 11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InputMethodManagerImpl::CandidateWindowClosed() { 11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FOR_EACH_OBSERVER(InputMethodManager::CandidateWindowObserver, 11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) candidate_window_observers_, 11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CandidateWindowClosed(this)); 11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InputMethodManagerImpl::MaybeInitializeCandidateWindowController() { 11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (candidate_window_controller_.get()) 11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) candidate_window_controller_.reset( 11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CandidateWindowController::CreateCandidateWindowController()); 1143a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) candidate_window_controller_->AddObserver(this); 11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace input_method 11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace chromeos 1148