Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/chromeos/input_method/input_method_manager_impl.h" | 5 #include "chrome/browser/chromeos/input_method/input_method_manager_impl.h" |
| 6 | 6 |
| 7 #include <algorithm> // std::find | 7 #include <algorithm> // std::find |
| 8 | 8 |
| 9 #include <sstream> | 9 #include <sstream> |
| 10 | 10 |
| 11 #include "ash/ime/input_method_menu_item.h" | 11 #include "ash/ime/input_method_menu_item.h" |
| 12 #include "ash/ime/input_method_menu_manager.h" | 12 #include "ash/ime/input_method_menu_manager.h" |
| 13 #include "base/basictypes.h" | 13 #include "base/basictypes.h" |
| 14 #include "base/bind.h" | 14 #include "base/bind.h" |
| 15 #include "base/location.h" | 15 #include "base/location.h" |
| 16 #include "base/memory/scoped_ptr.h" | 16 #include "base/memory/scoped_ptr.h" |
| 17 #include "base/metrics/histogram.h" | |
| 18 #include "base/metrics/sparse_histogram.h" | |
| 17 #include "base/prefs/pref_service.h" | 19 #include "base/prefs/pref_service.h" |
| 18 #include "base/strings/string_split.h" | 20 #include "base/strings/string_split.h" |
| 19 #include "base/strings/string_util.h" | 21 #include "base/strings/string_util.h" |
| 20 #include "base/strings/stringprintf.h" | 22 #include "base/strings/stringprintf.h" |
| 21 #include "base/sys_info.h" | 23 #include "base/sys_info.h" |
| 22 #include "chrome/browser/browser_process.h" | 24 #include "chrome/browser/browser_process.h" |
| 23 #include "chrome/browser/chromeos/input_method/candidate_window_controller.h" | 25 #include "chrome/browser/chromeos/input_method/candidate_window_controller.h" |
| 24 #include "chrome/browser/chromeos/input_method/component_extension_ime_manager_i mpl.h" | 26 #include "chrome/browser/chromeos/input_method/component_extension_ime_manager_i mpl.h" |
| 25 #include "chrome/browser/chromeos/input_method/input_method_engine.h" | 27 #include "chrome/browser/chromeos/input_method/input_method_engine.h" |
| 26 #include "chrome/browser/chromeos/language_preferences.h" | 28 #include "chrome/browser/chromeos/language_preferences.h" |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 43 namespace input_method { | 45 namespace input_method { |
| 44 | 46 |
| 45 namespace { | 47 namespace { |
| 46 | 48 |
| 47 bool Contains(const std::vector<std::string>& container, | 49 bool Contains(const std::vector<std::string>& container, |
| 48 const std::string& value) { | 50 const std::string& value) { |
| 49 return std::find(container.begin(), container.end(), value) != | 51 return std::find(container.begin(), container.end(), value) != |
| 50 container.end(); | 52 container.end(); |
| 51 } | 53 } |
| 52 | 54 |
| 55 enum InputMethodCategory { | |
| 56 INPUT_METHOD_CATEGORY_UNK = 0, | |
|
Ilya Sherman
2014/09/16 21:51:48
nit: Can "UNK" be expanded to "Unknown"?
Shu Chen
2014/09/17 15:17:28
Done.
| |
| 57 INPUT_METHOD_CATEGORY_XKB, // XKB input methods | |
|
Ilya Sherman
2014/09/16 21:51:48
What is XKB?
Shu Chen
2014/09/17 15:17:28
XKB (XKeyboard, used in XWindow) is the keyboard l
Ilya Sherman
2014/09/17 18:49:48
My point was that you should expand out the acrony
Shu Chen
2014/09/18 04:04:07
Sorry I wasn't clear enough. We rarely expand XKB
| |
| 58 INPUT_METHOD_CATEGORY_ZH, // Chinese input methods | |
| 59 INPUT_METHOD_CATEGORY_JA, // Japanese input methods | |
| 60 INPUT_METHOD_CATEGORY_KO, // Korean input methods | |
| 61 INPUT_METHOD_CATEGORY_M17N, // Multilingualization input methods | |
| 62 INPUT_METHOD_CATEGORY_T13N, // Transliteration input methods | |
| 63 INPUT_METHOD_CATEGORY_MAX | |
| 64 }; | |
| 65 | |
| 66 InputMethodCategory GetInputMethodCategory(const std::string& input_method_id, | |
| 67 char* first_char = NULL) { | |
| 68 const std::string component_id = | |
| 69 extension_ime_util::GetComponentIDByInputMethodID(input_method_id); | |
| 70 InputMethodCategory category = INPUT_METHOD_CATEGORY_UNK; | |
| 71 char ch = 0; | |
| 72 if (StartsWithASCII(component_id, "xkb:", true)) { | |
| 73 ch = component_id[4]; | |
| 74 category = INPUT_METHOD_CATEGORY_XKB; | |
| 75 } else if (StartsWithASCII(component_id, "zh-", true)) { | |
| 76 size_t pos = component_id.find("-t-i0-"); | |
| 77 if (pos > 0) | |
| 78 pos += 6; | |
| 79 ch = component_id[pos]; | |
| 80 category = INPUT_METHOD_CATEGORY_ZH; | |
| 81 } else if (StartsWithASCII(component_id, "nacl_mozc_", true)) { | |
| 82 ch = component_id[10]; | |
| 83 category = INPUT_METHOD_CATEGORY_JA; | |
| 84 } else if (StartsWithASCII(component_id, "hangul_", true)) { | |
| 85 ch = component_id[7]; | |
| 86 category = INPUT_METHOD_CATEGORY_KO; | |
| 87 } else if (StartsWithASCII(component_id, "vkd_", true)) { | |
| 88 ch = component_id[4]; | |
| 89 category = INPUT_METHOD_CATEGORY_M17N; | |
| 90 } else if (component_id.find("-t-i0-") > 0) { | |
| 91 ch = component_id[0]; | |
| 92 category = INPUT_METHOD_CATEGORY_T13N; | |
| 93 } | |
| 94 | |
| 95 if (first_char) | |
| 96 *first_char = ch; | |
| 97 return category; | |
| 98 } | |
| 99 | |
| 53 } // namespace | 100 } // namespace |
| 54 | 101 |
| 55 // ------------------------ InputMethodManagerImpl::StateImpl | 102 // ------------------------ InputMethodManagerImpl::StateImpl |
| 56 | 103 |
| 57 InputMethodManagerImpl::StateImpl::StateImpl(InputMethodManagerImpl* manager, | 104 InputMethodManagerImpl::StateImpl::StateImpl(InputMethodManagerImpl* manager, |
| 58 Profile* profile) | 105 Profile* profile) |
| 59 : profile(profile), manager_(manager) { | 106 : profile(profile), manager_(manager) { |
| 60 } | 107 } |
| 61 | 108 |
| 62 InputMethodManagerImpl::StateImpl::~StateImpl() { | 109 InputMethodManagerImpl::StateImpl::~StateImpl() { |
| (...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 322 new_active_input_method_ids_filtered.push_back(input_method_id); | 369 new_active_input_method_ids_filtered.push_back(input_method_id); |
| 323 } | 370 } |
| 324 active_input_method_ids.swap(new_active_input_method_ids_filtered); | 371 active_input_method_ids.swap(new_active_input_method_ids_filtered); |
| 325 manager_->MigrateInputMethods(&active_input_method_ids); | 372 manager_->MigrateInputMethods(&active_input_method_ids); |
| 326 | 373 |
| 327 manager_->ReconfigureIMFramework(this); | 374 manager_->ReconfigureIMFramework(this); |
| 328 | 375 |
| 329 // If |current_input_method| is no longer in |active_input_method_ids|, | 376 // If |current_input_method| is no longer in |active_input_method_ids|, |
| 330 // ChangeInputMethod() picks the first one in |active_input_method_ids|. | 377 // ChangeInputMethod() picks the first one in |active_input_method_ids|. |
| 331 ChangeInputMethod(current_input_method.id(), false); | 378 ChangeInputMethod(current_input_method.id(), false); |
| 379 | |
| 380 // Record histogram for active input method count. | |
| 381 UMA_HISTOGRAM_COUNTS("InputMethod.ActiveCount", | |
| 382 active_input_method_ids.size()); | |
| 383 | |
| 332 return true; | 384 return true; |
| 333 } | 385 } |
| 334 | 386 |
| 335 void InputMethodManagerImpl::StateImpl::ChangeInputMethod( | 387 void InputMethodManagerImpl::StateImpl::ChangeInputMethod( |
| 336 const std::string& input_method_id, | 388 const std::string& input_method_id, |
| 337 bool show_message) { | 389 bool show_message) { |
| 338 if (manager_->ui_session_ == STATE_TERMINATING) | 390 if (manager_->ui_session_ == STATE_TERMINATING) |
| 339 return; | 391 return; |
| 340 | 392 |
| 341 bool notify_menu = false; | 393 bool notify_menu = false; |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 355 if (descriptor->id() != current_input_method.id()) { | 407 if (descriptor->id() != current_input_method.id()) { |
| 356 previous_input_method = current_input_method; | 408 previous_input_method = current_input_method; |
| 357 current_input_method = *descriptor; | 409 current_input_method = *descriptor; |
| 358 notify_menu = true; | 410 notify_menu = true; |
| 359 } | 411 } |
| 360 | 412 |
| 361 // Always change input method even if it is the same. | 413 // Always change input method even if it is the same. |
| 362 // TODO(komatsu): Revisit if this is neccessary. | 414 // TODO(komatsu): Revisit if this is neccessary. |
| 363 if (IsActive()) | 415 if (IsActive()) |
| 364 manager_->ChangeInputMethodInternal(*descriptor, show_message, notify_menu); | 416 manager_->ChangeInputMethodInternal(*descriptor, show_message, notify_menu); |
| 417 manager_->RecordInputMethodUsage(current_input_method.id()); | |
| 365 } | 418 } |
| 366 | 419 |
| 367 bool InputMethodManagerImpl::StateImpl::MethodAwaitsExtensionLoad( | 420 bool InputMethodManagerImpl::StateImpl::MethodAwaitsExtensionLoad( |
| 368 const std::string& input_method_id) const { | 421 const std::string& input_method_id) const { |
| 369 // For 3rd party IME, when the user just logged in, SetEnabledExtensionImes | 422 // For 3rd party IME, when the user just logged in, SetEnabledExtensionImes |
| 370 // happens after activating the 3rd party IME. | 423 // happens after activating the 3rd party IME. |
| 371 // So here to record the 3rd party IME to be activated, and activate it | 424 // So here to record the 3rd party IME to be activated, and activate it |
| 372 // when SetEnabledExtensionImes happens later. | 425 // when SetEnabledExtensionImes happens later. |
| 373 return !InputMethodIsActivated(input_method_id) && | 426 return !InputMethodIsActivated(input_method_id) && |
| 374 extension_ime_util::IsExtensionIME(input_method_id); | 427 extension_ime_util::IsExtensionIME(input_method_id); |
| (...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 785 enable_extension_loading_(enable_extension_loading) { | 838 enable_extension_loading_(enable_extension_loading) { |
| 786 if (base::SysInfo::IsRunningOnChromeOS()) | 839 if (base::SysInfo::IsRunningOnChromeOS()) |
| 787 keyboard_.reset(ImeKeyboard::Create()); | 840 keyboard_.reset(ImeKeyboard::Create()); |
| 788 else | 841 else |
| 789 keyboard_.reset(new FakeImeKeyboard()); | 842 keyboard_.reset(new FakeImeKeyboard()); |
| 790 | 843 |
| 791 // Initializes the system IME list. | 844 // Initializes the system IME list. |
| 792 scoped_ptr<ComponentExtensionIMEManagerDelegate> comp_delegate( | 845 scoped_ptr<ComponentExtensionIMEManagerDelegate> comp_delegate( |
| 793 new ComponentExtensionIMEManagerImpl()); | 846 new ComponentExtensionIMEManagerImpl()); |
| 794 component_extension_ime_manager_->Initialize(comp_delegate.Pass()); | 847 component_extension_ime_manager_->Initialize(comp_delegate.Pass()); |
| 795 util_.ResetInputMethods( | 848 const InputMethodDescriptors& descriptors = |
| 796 component_extension_ime_manager_->GetAllIMEAsInputMethodDescriptor()); | 849 component_extension_ime_manager_->GetAllIMEAsInputMethodDescriptor(); |
| 850 util_.ResetInputMethods(descriptors); | |
| 851 | |
| 852 // Initializes the stat id map. | |
| 853 std::map<int, std::vector<std::string> > buckets; | |
| 854 for (InputMethodDescriptors::const_iterator it = descriptors.begin(); | |
| 855 it != descriptors.end(); ++it) { | |
| 856 char first_char; | |
| 857 int cat_id = static_cast<int>( | |
| 858 GetInputMethodCategory(it->id(), &first_char)); | |
| 859 int key = cat_id * 1000 + first_char; | |
| 860 buckets[key].push_back(it->id()); | |
| 861 } | |
| 862 std::vector<int> stat_id_custom_ranges; | |
|
Ilya Sherman
2014/09/16 21:51:48
nit: Looks like this is now unused.
Shu Chen
2014/09/17 15:17:28
Done.
| |
| 863 for (std::map<int, std::vector<std::string>>::iterator i = | |
| 864 buckets.begin(); i != buckets.end(); ++i) { | |
| 865 std::sort(i->second.begin(), i->second.end()); | |
| 866 for (size_t j = 0; j < i->second.size(); ++j) { | |
|
Ilya Sherman
2014/09/16 21:51:48
Somewhere, you should probably verify that size()
Shu Chen
2014/09/17 15:17:28
Done.
| |
| 867 int key = i->first * 100 + j; | |
| 868 stat_id_map_[i->second[j]] = key; | |
| 869 } | |
| 870 } | |
| 797 } | 871 } |
| 798 | 872 |
| 799 InputMethodManagerImpl::~InputMethodManagerImpl() { | 873 InputMethodManagerImpl::~InputMethodManagerImpl() { |
| 800 if (candidate_window_controller_.get()) | 874 if (candidate_window_controller_.get()) |
| 801 candidate_window_controller_->RemoveObserver(this); | 875 candidate_window_controller_->RemoveObserver(this); |
| 802 } | 876 } |
| 803 | 877 |
| 878 void InputMethodManagerImpl::RecordInputMethodUsage( | |
| 879 std::string input_method_id) { | |
| 880 UMA_HISTOGRAM_ENUMERATION("InputMethod.Category", | |
| 881 GetInputMethodCategory(input_method_id), | |
| 882 INPUT_METHOD_CATEGORY_MAX); | |
| 883 UMA_HISTOGRAM_SPARSE_SLOWLY("InputMethod.ID", | |
| 884 stat_id_map_[input_method_id]); | |
| 885 } | |
| 886 | |
| 804 void InputMethodManagerImpl::AddObserver( | 887 void InputMethodManagerImpl::AddObserver( |
| 805 InputMethodManager::Observer* observer) { | 888 InputMethodManager::Observer* observer) { |
| 806 observers_.AddObserver(observer); | 889 observers_.AddObserver(observer); |
| 807 } | 890 } |
| 808 | 891 |
| 809 void InputMethodManagerImpl::AddCandidateWindowObserver( | 892 void InputMethodManagerImpl::AddCandidateWindowObserver( |
| 810 InputMethodManager::CandidateWindowObserver* observer) { | 893 InputMethodManager::CandidateWindowObserver* observer) { |
| 811 candidate_window_observers_.AddObserver(observer); | 894 candidate_window_observers_.AddObserver(observer); |
| 812 } | 895 } |
| 813 | 896 |
| (...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1055 if (candidate_window_controller_.get()) | 1138 if (candidate_window_controller_.get()) |
| 1056 return; | 1139 return; |
| 1057 | 1140 |
| 1058 candidate_window_controller_.reset( | 1141 candidate_window_controller_.reset( |
| 1059 CandidateWindowController::CreateCandidateWindowController()); | 1142 CandidateWindowController::CreateCandidateWindowController()); |
| 1060 candidate_window_controller_->AddObserver(this); | 1143 candidate_window_controller_->AddObserver(this); |
| 1061 } | 1144 } |
| 1062 | 1145 |
| 1063 } // namespace input_method | 1146 } // namespace input_method |
| 1064 } // namespace chromeos | 1147 } // namespace chromeos |
| OLD | NEW |