input_method_manager_impl.cc revision a02191e04bc25c4935f804f2c080ae28663d096d
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) 9a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ash/ime/input_method_menu_item.h" 10a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ash/ime/input_method_menu_manager.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h" 12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/bind.h" 13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/location.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 15424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "base/prefs/pref_service.h" 165e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/string_util.h" 175e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/stringprintf.h" 185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/sys_info.h" 19424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "chrome/browser/browser_process.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/input_method/candidate_window_controller.h" 21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/chromeos/input_method/component_extension_ime_manager_impl.h" 22a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/browser/chromeos/input_method/input_method_engine.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/language_preferences.h" 24a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "chrome/browser/profiles/profile_manager.h" 25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chromeos/ime/component_extension_ime_manager.h" 26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chromeos/ime/extension_ime_util.h" 27a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "chromeos/ime/fake_ime_keyboard.h" 28a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "chromeos/ime/ime_keyboard.h" 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chromeos/ime/input_method_delegate.h" 30ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "third_party/icu/source/common/unicode/uloc.h" 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/accelerators/accelerator.h" 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace chromeos { 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace input_method { 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char nacl_mozc_jp_id[] = 39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "_comp_ime_fpfbhcjppmaeaijcidgiibchfbnhbeljnacl_mozc_jp"; 40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Contains(const std::vector<std::string>& container, 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& value) { 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return std::find(container.begin(), container.end(), value) != 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) container.end(); 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 49424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)bool InputMethodManagerImpl::IsLoginKeyboard( 50a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch const std::string& layout) const { 515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return util_.IsLoginKeyboard(layout); 52a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch} 53a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 54a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool InputMethodManagerImpl::MigrateXkbInputMethods( 55a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::vector<std::string>* input_method_ids) { 56a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return util_.MigrateXkbInputMethods(input_method_ids); 57a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 58a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)InputMethodManagerImpl::InputMethodManagerImpl( 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<InputMethodDelegate> delegate) 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : delegate_(delegate.Pass()), 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) state_(STATE_LOGIN_SCREEN), 63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) util_(delegate_.get(), GetSupportedInputMethods()), 64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) component_extension_ime_manager_(new ComponentExtensionIMEManager()), 65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) weak_ptr_factory_(this) { 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)InputMethodManagerImpl::~InputMethodManagerImpl() { 69a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (candidate_window_controller_.get()) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) candidate_window_controller_->RemoveObserver(this); 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InputMethodManagerImpl::AddObserver( 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InputMethodManager::Observer* observer) { 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observers_.AddObserver(observer); 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InputMethodManagerImpl::AddCandidateWindowObserver( 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InputMethodManager::CandidateWindowObserver* observer) { 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) candidate_window_observers_.AddObserver(observer); 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InputMethodManagerImpl::RemoveObserver( 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InputMethodManager::Observer* observer) { 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observers_.RemoveObserver(observer); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InputMethodManagerImpl::RemoveCandidateWindowObserver( 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InputMethodManager::CandidateWindowObserver* observer) { 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) candidate_window_observers_.RemoveObserver(observer); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InputMethodManagerImpl::SetState(State new_state) { 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const State old_state = state_; 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state_ = new_state; 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (state_) { 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_LOGIN_SCREEN: 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_BROWSER_SCREEN: 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (old_state == STATE_LOCK_SCREEN) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnScreenUnlocked(); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_LOCK_SCREEN: 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnScreenLocked(); 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case STATE_TERMINATING: { 107a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (candidate_window_controller_.get()) 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) candidate_window_controller_.reset(); 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_ptr<InputMethodDescriptors> 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)InputMethodManagerImpl::GetSupportedInputMethods() const { 116a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_ptr<InputMethodDescriptors> whitelist_imes = 117a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) whitelist_.GetSupportedInputMethods(); 118a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!extension_ime_util::UseWrappedExtensionKeyboardLayouts()) 119a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return whitelist_imes.Pass(); 120a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return scoped_ptr<InputMethodDescriptors>(new InputMethodDescriptors).Pass(); 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_ptr<InputMethodDescriptors> 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)InputMethodManagerImpl::GetActiveInputMethods() const { 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<InputMethodDescriptors> result(new InputMethodDescriptors); 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Build the active input method descriptors from the active input 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // methods cache |active_input_method_ids_|. 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < active_input_method_ids_.size(); ++i) { 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& input_method_id = active_input_method_ids_[i]; 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const InputMethodDescriptor* descriptor = 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) util_.GetInputMethodDescriptorFromId(input_method_id); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (descriptor) { 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->push_back(*descriptor); 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::map<std::string, InputMethodDescriptor>::const_iterator ix = 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extra_input_methods_.find(input_method_id); 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ix != extra_input_methods_.end()) 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->push_back(ix->second); 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "Descriptor is not found for: " << input_method_id; 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result->empty()) { 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Initially |active_input_method_ids_| is empty. browser_tests might take 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // this path. 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->push_back( 147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) InputMethodUtil::GetFallbackInputMethodDescriptor()); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return result.Pass(); 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 152a3f7b4e666c476898878fa745f637129375cd889Ben Murdochconst std::vector<std::string>& 153a3f7b4e666c476898878fa745f637129375cd889Ben MurdochInputMethodManagerImpl::GetActiveInputMethodIds() const { 154a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch return active_input_method_ids_; 155a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch} 156a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)size_t InputMethodManagerImpl::GetNumActiveInputMethods() const { 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return active_input_method_ids_.size(); 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const InputMethodDescriptor* InputMethodManagerImpl::GetInputMethodFromId( 1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& input_method_id) const { 1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const InputMethodDescriptor* ime = util_.GetInputMethodDescriptorFromId( 1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) input_method_id); 1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!ime) { 1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::map<std::string, InputMethodDescriptor>::const_iterator ix = 1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) extra_input_methods_.find(input_method_id); 1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (ix != extra_input_methods_.end()) 1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ime = &ix->second; 1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return ime; 1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void InputMethodManagerImpl::EnableLoginLayouts( 1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& language_code, 1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::vector<std::string>& initial_layouts) { 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (state_ == STATE_TERMINATING) 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // First, hardware keyboard layout should be shown. 1815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::vector<std::string> candidates = 1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) util_.GetHardwareLoginInputMethodIds(); 1835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Seocnd, locale based input method should be shown. 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add input methods associated with the language. 1865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::vector<std::string> layouts_from_locale; 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) util_.GetInputMethodIdsFromLanguageCode(language_code, 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kKeyboardLayoutsOnly, 1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &layouts_from_locale); 1905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) candidates.insert(candidates.end(), layouts_from_locale.begin(), 1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) layouts_from_locale.end()); 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<std::string> layouts; 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // First, add the initial input method ID, if it's requested, to 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // layouts, so it appears first on the list of active input 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // methods at the input language status menu. 1975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (size_t i = 0; i < initial_layouts.size(); ++i) { 1985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (util_.IsValidInputMethodId(initial_layouts[i])) { 1995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (IsLoginKeyboard(initial_layouts[i])) { 2005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) layouts.push_back(initial_layouts[i]); 2015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 2025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DVLOG(1) 2035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) << "EnableLoginLayouts: ignoring non-login initial keyboard layout:" 2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) << initial_layouts[i]; 2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else if (!initial_layouts[i].empty()) { 2075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DVLOG(1) << "EnableLoginLayouts: ignoring non-keyboard or invalid ID: " 2085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) << initial_layouts[i]; 2095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add candidates to layouts, while skipping duplicates. 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < candidates.size(); ++i) { 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& candidate = candidates[i]; 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Not efficient, but should be fine, as the two vectors are very 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // short (2-5 items). 217424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (!Contains(layouts, candidate) && IsLoginKeyboard(candidate)) 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) layouts.push_back(candidate); 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 221a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) MigrateXkbInputMethods(&layouts); 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) active_input_method_ids_.swap(layouts); 223a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 224a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Initialize candidate window controller and widgets such as 225a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // candidate window, infolist and mode indicator. Note, mode 226a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // indicator is used by only keyboard layout input methods. 227a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (active_input_method_ids_.size() > 1) 228a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) MaybeInitializeCandidateWindowController(); 229a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 2305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // you can pass empty |initial_layout|. 231a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ChangeInputMethod(initial_layouts.empty() ? "" : 232a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) extension_ime_util::GetInputMethodIDByKeyboardLayout( 233a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) initial_layouts[0])); 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 236a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch// Adds new input method to given list. 237a3f7b4e666c476898878fa745f637129375cd889Ben Murdochbool InputMethodManagerImpl::EnableInputMethodImpl( 238a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch const std::string& input_method_id, 239f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) std::vector<std::string>* new_active_input_method_ids) const { 240f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(new_active_input_method_ids); 241a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch if (!util_.IsValidInputMethodId(input_method_id)) { 242a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch DVLOG(1) << "EnableInputMethod: Invalid ID: " << input_method_id; 243a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch return false; 244a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch } 245a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 246f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!Contains(*new_active_input_method_ids, input_method_id)) 247f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) new_active_input_method_ids->push_back(input_method_id); 248a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 249a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch return true; 250a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch} 251a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 252a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch// Starts or stops the system input method framework as needed. 253a3f7b4e666c476898878fa745f637129375cd889Ben Murdochvoid InputMethodManagerImpl::ReconfigureIMFramework() { 254a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) LoadNecessaryComponentExtensions(); 255f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 256f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Initialize candidate window controller and widgets such as 257f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // candidate window, infolist and mode indicator. Note, mode 258f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // indicator is used by only keyboard layout input methods. 259a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) MaybeInitializeCandidateWindowController(); 260a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch} 261a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 262a3f7b4e666c476898878fa745f637129375cd889Ben Murdochbool InputMethodManagerImpl::EnableInputMethod( 263a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch const std::string& input_method_id) { 264f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!EnableInputMethodImpl(input_method_id, &active_input_method_ids_)) 265a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch return false; 266a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 267a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch ReconfigureIMFramework(); 268a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch return true; 269a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch} 270a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 2715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool InputMethodManagerImpl::ReplaceEnabledInputMethods( 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<std::string>& new_active_input_method_ids) { 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (state_ == STATE_TERMINATING) 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Filter unknown or obsolete IDs. 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<std::string> new_active_input_method_ids_filtered; 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 279a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch for (size_t i = 0; i < new_active_input_method_ids.size(); ++i) 280a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch EnableInputMethodImpl(new_active_input_method_ids[i], 281f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) &new_active_input_method_ids_filtered); 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (new_active_input_method_ids_filtered.empty()) { 2845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DVLOG(1) << "ReplaceEnabledInputMethods: No valid input method ID"; 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Copy extension IDs to |new_active_input_method_ids_filtered|. We have to 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // keep relative order of the extension input method IDs. 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < active_input_method_ids_.size(); ++i) { 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& input_method_id = active_input_method_ids_[i]; 292c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (extension_ime_util::IsExtensionIME(input_method_id)) 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new_active_input_method_ids_filtered.push_back(input_method_id); 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) active_input_method_ids_.swap(new_active_input_method_ids_filtered); 296a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) MigrateXkbInputMethods(&active_input_method_ids_); 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 298a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch ReconfigureIMFramework(); 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If |current_input_method| is no longer in |active_input_method_ids_|, 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ChangeInputMethod() picks the first one in |active_input_method_ids_|. 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ChangeInputMethod(current_input_method_.id()); 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InputMethodManagerImpl::ChangeInputMethod( 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& input_method_id) { 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ChangeInputMethodInternal(input_method_id, false); 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 311a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)bool InputMethodManagerImpl::ChangeInputMethodInternal( 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& input_method_id, 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool show_message) { 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (state_ == STATE_TERMINATING) 315a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) return false; 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string input_method_id_to_switch = input_method_id; 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Sanity check. 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!InputMethodIsActivated(input_method_id)) { 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<InputMethodDescriptors> input_methods(GetActiveInputMethods()); 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!input_methods->empty()); 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) input_method_id_to_switch = input_methods->at(0).id(); 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!input_method_id.empty()) { 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "Can't change the current input method to " 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << input_method_id << " since the engine is not enabled. " 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "Switch to " << input_method_id_to_switch << " instead."; 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!component_extension_ime_manager_->IsInitialized() && 332a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) (!InputMethodUtil::IsKeyboardLayout(input_method_id_to_switch) || 333a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) extension_ime_util::IsKeyboardLayoutExtension( 334a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) input_method_id_to_switch))) { 335f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // We can't change input method before the initialization of 336f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // component extension ime manager. ChangeInputMethod will be 337f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // called with |pending_input_method_| when the initialization is 338f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // done. 33990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) pending_input_method_ = input_method_id_to_switch; 34090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return false; 34190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 34290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) pending_input_method_.clear(); 343f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 344f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Hide candidate window and info list. 345f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (candidate_window_controller_.get()) 346f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) candidate_window_controller_->Hide(); 347f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 3485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Disable the current engine handler. 3495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) IMEEngineHandlerInterface* engine = 3505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) IMEBridge::Get()->GetCurrentEngineHandler(); 3515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (engine) 3525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) engine->Disable(); 3535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Configure the next engine handler. 355a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (InputMethodUtil::IsKeyboardLayout(input_method_id_to_switch) && 356a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) !extension_ime_util::IsKeyboardLayoutExtension( 357a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) input_method_id_to_switch)) { 3585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) IMEBridge::Get()->SetCurrentEngineHandler(NULL); 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) IMEEngineHandlerInterface* next_engine = 361a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch profile_engine_map_[GetProfile()][input_method_id_to_switch]; 362a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (next_engine) { 363a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch IMEBridge::Get()->SetCurrentEngineHandler(next_engine); 364f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) next_engine->Enable(); 365a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch } 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // TODO(komatsu): Check if it is necessary to perform the above routine 3695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // when the current input method is equal to |input_method_id_to_swich|. 3705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (current_input_method_.id() != input_method_id_to_switch) { 371f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Clear property list. Property list would be updated by 3725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // extension IMEs via InputMethodEngine::(Set|Update)MenuItems. 373f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // If the current input method is a keyboard layout, empty 374f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // properties are sufficient. 375a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const ash::ime::InputMethodMenuItemList empty_menu_item_list; 376a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ash::ime::InputMethodMenuManager* input_method_menu_manager = 377a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ash::ime::InputMethodMenuManager::GetInstance(); 378a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) input_method_menu_manager->SetCurrentInputMethodMenuItemList( 379a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) empty_menu_item_list); 380a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const InputMethodDescriptor* descriptor = NULL; 3825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (extension_ime_util::IsExtensionIME(input_method_id_to_switch)) { 3835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(extra_input_methods_.find(input_method_id_to_switch) != 3845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) extra_input_methods_.end()); 3855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) descriptor = &(extra_input_methods_[input_method_id_to_switch]); 3865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) descriptor = 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) util_.GetInputMethodDescriptorFromId(input_method_id_to_switch); 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(descriptor); 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) previous_input_method_ = current_input_method_; 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) current_input_method_ = *descriptor; 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Change the keyboard layout to a preferred layout for the input method. 397a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (!keyboard_->SetCurrentKeyboardLayoutByName( 398c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) current_input_method_.GetPreferredKeyboardLayout())) { 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Failed to change keyboard layout to " 400c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) << current_input_method_.GetPreferredKeyboardLayout(); 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Update input method indicators (e.g. "US", "DV") in Chrome windows. 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FOR_EACH_OBSERVER(InputMethodManager::Observer, 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observers_, 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InputMethodChanged(this, show_message)); 407a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) return true; 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 410c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void InputMethodManagerImpl::OnComponentExtensionInitialized( 411c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<ComponentExtensionIMEManagerDelegate> delegate) { 412c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 413c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) component_extension_ime_manager_->Initialize(delegate.Pass()); 414c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) util_.SetComponentExtensions( 415c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) component_extension_ime_manager_->GetAllIMEAsInputMethodDescriptor()); 416c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 417c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LoadNecessaryComponentExtensions(); 418c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 41990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!pending_input_method_.empty()) 42090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ChangeInputMethodInternal(pending_input_method_, false); 421c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 422c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 423c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void InputMethodManagerImpl::LoadNecessaryComponentExtensions() { 424c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!component_extension_ime_manager_->IsInitialized()) 425c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 426c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Load component extensions but also update |active_input_method_ids_| as 427c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // some component extension IMEs may have been removed from the Chrome OS 428c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // image. If specified component extension IME no longer exists, falling back 429c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // to an existing IME. 430a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::vector<std::string> unfiltered_input_method_ids; 431a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) unfiltered_input_method_ids.swap(active_input_method_ids_); 432c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (size_t i = 0; i < unfiltered_input_method_ids.size(); ++i) { 433f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!extension_ime_util::IsComponentExtensionIME( 434c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) unfiltered_input_method_ids[i])) { 435c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Legacy IMEs or xkb layouts are alwayes active. 436c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) active_input_method_ids_.push_back(unfiltered_input_method_ids[i]); 437c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else if (component_extension_ime_manager_->IsWhitelisted( 438c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) unfiltered_input_method_ids[i])) { 439c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) component_extension_ime_manager_->LoadComponentExtensionIME( 440c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) unfiltered_input_method_ids[i]); 441c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) active_input_method_ids_.push_back(unfiltered_input_method_ids[i]); 442c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 443c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 444a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // TODO(shuchen): move this call in ComponentExtensionIMEManager. 445a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) component_extension_ime_manager_->NotifyInitialized(); 446c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 447c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 448a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void InputMethodManagerImpl::ActivateInputMethodMenuItem( 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& key) { 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!key.empty()); 451f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 452a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (ash::ime::InputMethodMenuManager::GetInstance()-> 453a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) HasInputMethodMenuItemForKey(key)) { 454a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) IMEEngineHandlerInterface* engine = 455a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) IMEBridge::Get()->GetCurrentEngineHandler(); 456a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (engine) 457a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) engine->PropertyActivate(key); 458a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 459f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 460f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 461a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DVLOG(1) << "ActivateInputMethodMenuItem: unknown key: " << key; 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InputMethodManagerImpl::AddInputMethodExtension( 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& id, 466a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) InputMethodEngineInterface* engine) { 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (state_ == STATE_TERMINATING) 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 470c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!extension_ime_util::IsExtensionIME(id) && 471f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) !extension_ime_util::IsComponentExtensionIME(id)) { 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << id << " is not a valid extension input method ID."; 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(engine); 4775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const InputMethodDescriptor& descriptor = engine->GetDescriptor(); 4795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) extra_input_methods_[id] = descriptor; 480b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (Contains(enabled_extension_imes_, id) && 481f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) !extension_ime_util::IsComponentExtensionIME(id)) { 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!Contains(active_input_method_ids_, id)) { 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) active_input_method_ids_.push_back(id); 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "AddInputMethodExtension: alread added: " 4865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) << id << ", " << descriptor.name(); 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Call Start() anyway, just in case. 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ensure that the input method daemon is running. 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MaybeInitializeCandidateWindowController(); 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 494a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch profile_engine_map_[GetProfile()][id] = engine; 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InputMethodManagerImpl::RemoveInputMethodExtension(const std::string& id) { 498c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!extension_ime_util::IsExtensionIME(id)) 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << id << " is not a valid extension input method ID."; 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<std::string>::iterator i = std::find( 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) active_input_method_ids_.begin(), active_input_method_ids_.end(), id); 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i != active_input_method_ids_.end()) 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) active_input_method_ids_.erase(i); 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extra_input_methods_.erase(id); 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If |current_input_method| is no longer in |active_input_method_ids_|, 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // switch to the first one in |active_input_method_ids_|. 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ChangeInputMethod(current_input_method_.id()); 5105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (IMEBridge::Get()->GetCurrentEngineHandler() == 512a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch profile_engine_map_[GetProfile()][id]) 5135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) IMEBridge::Get()->SetCurrentEngineHandler(NULL); 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InputMethodManagerImpl::GetInputMethodExtensions( 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InputMethodDescriptors* result) { 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Build the extension input method descriptors from the extra input 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // methods cache |extra_input_methods_|. 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::map<std::string, InputMethodDescriptor>::iterator iter; 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (iter = extra_input_methods_.begin(); iter != extra_input_methods_.end(); 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++iter) { 523c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (extension_ime_util::IsExtensionIME(iter->first)) 524c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) result->push_back(iter->second); 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 528b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)void InputMethodManagerImpl::SetEnabledExtensionImes( 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<std::string>* ids) { 530b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) enabled_extension_imes_.clear(); 531b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) enabled_extension_imes_.insert(enabled_extension_imes_.end(), 532b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) ids->begin(), 533b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) ids->end()); 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool active_imes_changed = false; 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::map<std::string, InputMethodDescriptor>::iterator extra_iter = 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extra_input_methods_.begin(); extra_iter != extra_input_methods_.end(); 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++extra_iter) { 540f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (extension_ime_util::IsComponentExtensionIME( 541c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) extra_iter->first)) 542c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) continue; // Do not filter component extension. 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<std::string>::iterator active_iter = std::find( 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) active_input_method_ids_.begin(), active_input_method_ids_.end(), 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extra_iter->first); 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool active = active_iter != active_input_method_ids_.end(); 548b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) bool enabled = Contains(enabled_extension_imes_, extra_iter->first); 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 550b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (active && !enabled) 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) active_input_method_ids_.erase(active_iter); 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 553b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!active && enabled) 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) active_input_method_ids_.push_back(extra_iter->first); 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 556b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (active == !enabled) 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) active_imes_changed = true; 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (active_imes_changed) { 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MaybeInitializeCandidateWindowController(); 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If |current_input_method| is no longer in |active_input_method_ids_|, 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // switch to the first one in |active_input_method_ids_|. 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ChangeInputMethod(current_input_method_.id()); 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void InputMethodManagerImpl::SetInputMethodLoginDefault() { 570424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Set up keyboards. For example, when |locale| is "en-US", enable US qwerty 571424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // and US dvorak keyboard layouts. 572424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (g_browser_process && g_browser_process->local_state()) { 573424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const std::string locale = g_browser_process->GetApplicationLocale(); 574424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // If the preferred keyboard for the login screen has been saved, use it. 575424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) PrefService* prefs = g_browser_process->local_state(); 576424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) std::string initial_input_method_id = 577424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) prefs->GetString(chromeos::language_prefs::kPreferredKeyboardLayout); 5785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::vector<std::string> input_methods_to_be_enabled; 579424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (initial_input_method_id.empty()) { 580424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // If kPreferredKeyboardLayout is not specified, use the hardware layout. 5815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) input_methods_to_be_enabled = util_.GetHardwareLoginInputMethodIds(); 5825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 5835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) input_methods_to_be_enabled.push_back(initial_input_method_id); 584424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 5855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EnableLoginLayouts(locale, input_methods_to_be_enabled); 586424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 587424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 588424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool InputMethodManagerImpl::SwitchToNextInputMethod() { 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Sanity checks. 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (active_input_method_ids_.empty()) { 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "active input method is empty"; 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 595a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (current_input_method_.id().empty()) { 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "current_input_method_ is unknown"; 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 601a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) // Do not consume key event if there is only one input method is enabled. 602a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) // Ctrl+Space or Alt+Shift may be used by other application. 603a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) if (active_input_method_ids_.size() == 1) 604a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) return false; 605a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Find the next input method and switch to it. 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SwitchToNextInputMethodInternal(active_input_method_ids_, 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) current_input_method_.id()); 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 612a3f7b4e666c476898878fa745f637129375cd889Ben Murdochbool InputMethodManagerImpl::SwitchToPreviousInputMethod( 613a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch const ui::Accelerator& accelerator) { 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Sanity check. 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (active_input_method_ids_.empty()) { 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "active input method is empty"; 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 620a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) // Do not consume key event if there is only one input method is enabled. 621a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) // Ctrl+Space or Alt+Shift may be used by other application. 622a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) if (active_input_method_ids_.size() == 1) 623a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) return false; 624a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 625a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch if (accelerator.type() == ui::ET_KEY_RELEASED) 626a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch return true; 627a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (previous_input_method_.id().empty() || 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) previous_input_method_.id() == current_input_method_.id()) { 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SwitchToNextInputMethod(); 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<std::string>::const_iterator iter = 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::find(active_input_method_ids_.begin(), 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) active_input_method_ids_.end(), 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) previous_input_method_.id()); 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (iter == active_input_method_ids_.end()) { 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // previous_input_method_ is not supported. 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SwitchToNextInputMethod(); 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ChangeInputMethodInternal(*iter, true); 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool InputMethodManagerImpl::SwitchInputMethod( 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ui::Accelerator& accelerator) { 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Sanity check. 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (active_input_method_ids_.empty()) { 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "active input method is empty"; 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Get the list of input method ids for the |accelerator|. For example, get 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // { "mozc-hangul", "xkb:kr:kr104:kor" } for ui::VKEY_DBE_SBCSCHAR. 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<std::string> input_method_ids_to_switch; 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (accelerator.key_code()) { 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ui::VKEY_CONVERT: // Henkan key on JP106 keyboard 658c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) input_method_ids_to_switch.push_back(nacl_mozc_jp_id); 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ui::VKEY_NONCONVERT: // Muhenkan key on JP106 keyboard 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) input_method_ids_to_switch.push_back("xkb:jp::jpn"); 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ui::VKEY_DBE_SBCSCHAR: // ZenkakuHankaku key on JP106 keyboard 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ui::VKEY_DBE_DBCSCHAR: 665c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) input_method_ids_to_switch.push_back(nacl_mozc_jp_id); 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) input_method_ids_to_switch.push_back("xkb:jp::jpn"); 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (input_method_ids_to_switch.empty()) { 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "Unexpected VKEY: " << accelerator.key_code(); 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 677a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) MigrateXkbInputMethods(&input_method_ids_to_switch); 678a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Obtain the intersection of input_method_ids_to_switch and 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // active_input_method_ids_. The order of IDs in active_input_method_ids_ is 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // preserved. 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<std::string> ids; 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < input_method_ids_to_switch.size(); ++i) { 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& id = input_method_ids_to_switch[i]; 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (Contains(active_input_method_ids_, id)) 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ids.push_back(id); 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ids.empty()) { 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // No input method for the accelerator is active. For example, we should 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // just ignore VKEY_HANGUL when mozc-hangul is not active. 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SwitchToNextInputMethodInternal(ids, current_input_method_.id()); 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; // consume the accelerator. 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InputMethodManagerImpl::SwitchToNextInputMethodInternal( 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<std::string>& input_method_ids, 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& current_input_method_id) { 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<std::string>::const_iterator iter = 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::find(input_method_ids.begin(), 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) input_method_ids.end(), 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) current_input_method_id); 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (iter != input_method_ids.end()) 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++iter; 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (iter == input_method_ids.end()) 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iter = input_method_ids.begin(); 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ChangeInputMethodInternal(*iter, true); 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)InputMethodDescriptor InputMethodManagerImpl::GetCurrentInputMethod() const { 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (current_input_method_.id().empty()) 714c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return InputMethodUtil::GetFallbackInputMethodDescriptor(); 7155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return current_input_method_; 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 719effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochbool InputMethodManagerImpl::IsISOLevel5ShiftUsedByCurrentInputMethod() const { 720a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return keyboard_->IsISOLevel5ShiftAvailable(); 721effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 722effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 723effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochbool InputMethodManagerImpl::IsAltGrUsedByCurrentInputMethod() const { 724a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return keyboard_->IsAltGrAvailable(); 725effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 726effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 727a02191e04bc25c4935f804f2c080ae28663d096dBen MurdochImeKeyboard* InputMethodManagerImpl::GetImeKeyboard() { 728a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return keyboard_.get(); 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)InputMethodUtil* InputMethodManagerImpl::GetInputMethodUtil() { 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return &util_; 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)ComponentExtensionIMEManager* 736c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) InputMethodManagerImpl::GetComponentExtensionIMEManager() { 737c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 738c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return component_extension_ime_manager_.get(); 739c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 740c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 741c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void InputMethodManagerImpl::InitializeComponentExtension() { 742c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ComponentExtensionIMEManagerImpl* impl = 743c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) new ComponentExtensionIMEManagerImpl(); 744c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<ComponentExtensionIMEManagerDelegate> delegate(impl); 745c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) impl->InitializeAsync(base::Bind( 746c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) &InputMethodManagerImpl::OnComponentExtensionInitialized, 747c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 748c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Passed(&delegate))); 749c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 750c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 751c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void InputMethodManagerImpl::Init(base::SequencedTaskRunner* ui_task_runner) { 752c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (base::SysInfo::IsRunningOnChromeOS()) 755a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch keyboard_.reset(ImeKeyboard::Create()); 7565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) else 757a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch keyboard_.reset(new FakeImeKeyboard()); 758c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 759c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // We can't call impl->Initialize here, because file thread is not available 760c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // at this moment. 761c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ui_task_runner->PostTask( 762c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, 763c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(&InputMethodManagerImpl::InitializeComponentExtension, 764c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr())); 7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InputMethodManagerImpl::SetCandidateWindowControllerForTesting( 7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CandidateWindowController* candidate_window_controller) { 7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) candidate_window_controller_.reset(candidate_window_controller); 7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) candidate_window_controller_->AddObserver(this); 7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 773a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid InputMethodManagerImpl::SetImeKeyboardForTesting(ImeKeyboard* keyboard) { 774a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch keyboard_.reset(keyboard); 7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 777c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void InputMethodManagerImpl::InitializeComponentExtensionForTesting( 778c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<ComponentExtensionIMEManagerDelegate> delegate) { 779c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) OnComponentExtensionInitialized(delegate.Pass()); 780c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 781c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 782a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void InputMethodManagerImpl::CandidateClicked(int index) { 7835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) IMEEngineHandlerInterface* engine = 7845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) IMEBridge::Get()->GetCurrentEngineHandler(); 785a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (engine) 786a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) engine->CandidateClicked(index); 787a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 788a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InputMethodManagerImpl::CandidateWindowOpened() { 7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FOR_EACH_OBSERVER(InputMethodManager::CandidateWindowObserver, 7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) candidate_window_observers_, 7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CandidateWindowOpened(this)); 7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InputMethodManagerImpl::CandidateWindowClosed() { 7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FOR_EACH_OBSERVER(InputMethodManager::CandidateWindowObserver, 7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) candidate_window_observers_, 7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CandidateWindowClosed(this)); 7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InputMethodManagerImpl::OnScreenLocked() { 8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) saved_previous_input_method_ = previous_input_method_; 8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) saved_current_input_method_ = current_input_method_; 8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) saved_active_input_method_ids_ = active_input_method_ids_; 8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::set<std::string> added_ids_; 8075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 8085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::vector<std::string>& hardware_keyboard_ids = 8095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) util_.GetHardwareLoginInputMethodIds(); 8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) active_input_method_ids_.clear(); 8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < saved_active_input_method_ids_.size(); ++i) { 8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& input_method_id = saved_active_input_method_ids_[i]; 8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Skip if it's not a keyboard layout. Drop input methods including 8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // extension ones. 8165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!IsLoginKeyboard(input_method_id) || 8175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) added_ids_.find(input_method_id) != added_ids_.end()) 8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) active_input_method_ids_.push_back(input_method_id); 8205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) added_ids_.insert(input_method_id); 8215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 8225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 8235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // We'll add the hardware keyboard if it's not included in 8245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // |active_input_method_ids_| so that the user can always use the hardware 8255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // keyboard on the screen locker. 8265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (size_t i = 0; i < hardware_keyboard_ids.size(); ++i) { 8275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (added_ids_.find(hardware_keyboard_ids[i]) == added_ids_.end()) { 8285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) active_input_method_ids_.push_back(hardware_keyboard_ids[i]); 8295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) added_ids_.insert(hardware_keyboard_ids[i]); 8305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ChangeInputMethod(current_input_method_.id()); 8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InputMethodManagerImpl::OnScreenUnlocked() { 8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) previous_input_method_ = saved_previous_input_method_; 8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) current_input_method_ = saved_current_input_method_; 8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) active_input_method_ids_ = saved_active_input_method_ids_; 8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ChangeInputMethod(current_input_method_.id()); 8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool InputMethodManagerImpl::InputMethodIsActivated( 8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& input_method_id) { 8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Contains(active_input_method_ids_, input_method_id); 8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InputMethodManagerImpl::MaybeInitializeCandidateWindowController() { 8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (candidate_window_controller_.get()) 8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) candidate_window_controller_.reset( 8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CandidateWindowController::CreateCandidateWindowController()); 855a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) candidate_window_controller_->AddObserver(this); 8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 858a02191e04bc25c4935f804f2c080ae28663d096dBen MurdochProfile* InputMethodManagerImpl::GetProfile() const { 859a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return ProfileManager::GetActiveUserProfile(); 860a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch} 861a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace input_method 8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace chromeos 864