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" | |
| 17 #include "base/prefs/pref_service.h" | 18 #include "base/prefs/pref_service.h" |
| 18 #include "base/strings/string_split.h" | 19 #include "base/strings/string_split.h" |
| 19 #include "base/strings/string_util.h" | 20 #include "base/strings/string_util.h" |
| 20 #include "base/strings/stringprintf.h" | 21 #include "base/strings/stringprintf.h" |
| 21 #include "base/sys_info.h" | 22 #include "base/sys_info.h" |
| 22 #include "chrome/browser/browser_process.h" | 23 #include "chrome/browser/browser_process.h" |
| 23 #include "chrome/browser/chromeos/input_method/candidate_window_controller.h" | 24 #include "chrome/browser/chromeos/input_method/candidate_window_controller.h" |
| 24 #include "chrome/browser/chromeos/input_method/component_extension_ime_manager_i mpl.h" | 25 #include "chrome/browser/chromeos/input_method/component_extension_ime_manager_i mpl.h" |
| 25 #include "chrome/browser/chromeos/input_method/input_method_engine.h" | 26 #include "chrome/browser/chromeos/input_method/input_method_engine.h" |
| 26 #include "chrome/browser/chromeos/language_preferences.h" | 27 #include "chrome/browser/chromeos/language_preferences.h" |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 43 namespace input_method { | 44 namespace input_method { |
| 44 | 45 |
| 45 namespace { | 46 namespace { |
| 46 | 47 |
| 47 bool Contains(const std::vector<std::string>& container, | 48 bool Contains(const std::vector<std::string>& container, |
| 48 const std::string& value) { | 49 const std::string& value) { |
| 49 return std::find(container.begin(), container.end(), value) != | 50 return std::find(container.begin(), container.end(), value) != |
| 50 container.end(); | 51 container.end(); |
| 51 } | 52 } |
| 52 | 53 |
| 54 enum InputMethodCategory { | |
| 55 INPUT_METHOD_CATEGORY_UNK = 0, | |
| 56 INPUT_METHOD_CATEGORY_XKB, | |
| 57 INPUT_METHOD_CATEGORY_ZH, | |
| 58 INPUT_METHOD_CATEGORY_JA, | |
| 59 INPUT_METHOD_CATEGORY_KO, | |
| 60 INPUT_METHOD_CATEGORY_M17N, | |
| 61 INPUT_METHOD_CATEGORY_T13N, | |
| 62 INPUT_METHOD_CATEGORY_MAX | |
|
Ilya Sherman
2014/09/16 00:00:28
nit: I find these names needlessly cryptic. Would
Shu Chen
2014/09/16 16:36:30
Done. I've added comments.
| |
| 63 }; | |
| 64 | |
| 65 InputMethodCategory GetInputMethodCategory(const std::string& input_method_id, | |
| 66 char* first_char = NULL) { | |
| 67 const std::string component_id = | |
| 68 extension_ime_util::GetComponentIDByInputMethodID(input_method_id); | |
| 69 InputMethodCategory category = INPUT_METHOD_CATEGORY_UNK; | |
| 70 char ch = 0; | |
| 71 if (StartsWithASCII(component_id, "xkb:", true)) { | |
| 72 ch = component_id[4]; | |
| 73 category = INPUT_METHOD_CATEGORY_XKB; | |
| 74 } else if (StartsWithASCII(component_id, "zh-", true)) { | |
| 75 size_t pos = component_id.find("-t-i0-"); | |
| 76 if (pos > 0) | |
| 77 pos += 6; | |
| 78 ch = component_id[pos]; | |
| 79 category = INPUT_METHOD_CATEGORY_ZH; | |
| 80 } else if (StartsWithASCII(component_id, "nacl_mozc_", true)) { | |
| 81 ch = component_id[10]; | |
| 82 category = INPUT_METHOD_CATEGORY_JA; | |
| 83 } else if (StartsWithASCII(component_id, "hangul_", true)) { | |
| 84 ch = component_id[7]; | |
| 85 category = INPUT_METHOD_CATEGORY_KO; | |
| 86 } else if (StartsWithASCII(component_id, "vkd_", true)) { | |
| 87 ch = component_id[4]; | |
| 88 category = INPUT_METHOD_CATEGORY_M17N; | |
| 89 } else if (component_id.find("-t-i0-") > 0) { | |
| 90 ch = component_id[0]; | |
| 91 category = INPUT_METHOD_CATEGORY_T13N; | |
| 92 } | |
| 93 | |
| 94 if (first_char) | |
| 95 *first_char = ch; | |
| 96 return category; | |
| 97 } | |
| 98 | |
| 53 } // namespace | 99 } // namespace |
| 54 | 100 |
| 55 // ------------------------ InputMethodManagerImpl::StateImpl | 101 // ------------------------ InputMethodManagerImpl::StateImpl |
| 56 | 102 |
| 57 InputMethodManagerImpl::StateImpl::StateImpl(InputMethodManagerImpl* manager, | 103 InputMethodManagerImpl::StateImpl::StateImpl(InputMethodManagerImpl* manager, |
| 58 Profile* profile) | 104 Profile* profile) |
| 59 : profile(profile), manager_(manager) { | 105 : profile(profile), manager_(manager) { |
| 60 } | 106 } |
| 61 | 107 |
| 62 InputMethodManagerImpl::StateImpl::~StateImpl() { | 108 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); | 368 new_active_input_method_ids_filtered.push_back(input_method_id); |
| 323 } | 369 } |
| 324 active_input_method_ids.swap(new_active_input_method_ids_filtered); | 370 active_input_method_ids.swap(new_active_input_method_ids_filtered); |
| 325 manager_->MigrateInputMethods(&active_input_method_ids); | 371 manager_->MigrateInputMethods(&active_input_method_ids); |
| 326 | 372 |
| 327 manager_->ReconfigureIMFramework(this); | 373 manager_->ReconfigureIMFramework(this); |
| 328 | 374 |
| 329 // If |current_input_method| is no longer in |active_input_method_ids|, | 375 // If |current_input_method| is no longer in |active_input_method_ids|, |
| 330 // ChangeInputMethod() picks the first one in |active_input_method_ids|. | 376 // ChangeInputMethod() picks the first one in |active_input_method_ids|. |
| 331 ChangeInputMethod(current_input_method.id(), false); | 377 ChangeInputMethod(current_input_method.id(), false); |
| 378 | |
| 379 // Record histogram for active input method count. | |
| 380 UMA_HISTOGRAM_COUNTS("InputMethod.ActiveCount", | |
| 381 active_input_method_ids.size()); | |
| 382 | |
| 332 return true; | 383 return true; |
| 333 } | 384 } |
| 334 | 385 |
| 335 void InputMethodManagerImpl::StateImpl::ChangeInputMethod( | 386 void InputMethodManagerImpl::StateImpl::ChangeInputMethod( |
| 336 const std::string& input_method_id, | 387 const std::string& input_method_id, |
| 337 bool show_message) { | 388 bool show_message) { |
| 338 if (manager_->ui_session_ == STATE_TERMINATING) | 389 if (manager_->ui_session_ == STATE_TERMINATING) |
| 339 return; | 390 return; |
| 340 | 391 |
| 341 bool notify_menu = false; | 392 bool notify_menu = false; |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 355 if (descriptor->id() != current_input_method.id()) { | 406 if (descriptor->id() != current_input_method.id()) { |
| 356 previous_input_method = current_input_method; | 407 previous_input_method = current_input_method; |
| 357 current_input_method = *descriptor; | 408 current_input_method = *descriptor; |
| 358 notify_menu = true; | 409 notify_menu = true; |
| 359 } | 410 } |
| 360 | 411 |
| 361 // Always change input method even if it is the same. | 412 // Always change input method even if it is the same. |
| 362 // TODO(komatsu): Revisit if this is neccessary. | 413 // TODO(komatsu): Revisit if this is neccessary. |
| 363 if (IsActive()) | 414 if (IsActive()) |
| 364 manager_->ChangeInputMethodInternal(*descriptor, show_message, notify_menu); | 415 manager_->ChangeInputMethodInternal(*descriptor, show_message, notify_menu); |
| 416 manager_->RecordInputMethodUsage(current_input_method.id()); | |
| 365 } | 417 } |
| 366 | 418 |
| 367 bool InputMethodManagerImpl::StateImpl::MethodAwaitsExtensionLoad( | 419 bool InputMethodManagerImpl::StateImpl::MethodAwaitsExtensionLoad( |
| 368 const std::string& input_method_id) const { | 420 const std::string& input_method_id) const { |
| 369 // For 3rd party IME, when the user just logged in, SetEnabledExtensionImes | 421 // For 3rd party IME, when the user just logged in, SetEnabledExtensionImes |
| 370 // happens after activating the 3rd party IME. | 422 // happens after activating the 3rd party IME. |
| 371 // So here to record the 3rd party IME to be activated, and activate it | 423 // So here to record the 3rd party IME to be activated, and activate it |
| 372 // when SetEnabledExtensionImes happens later. | 424 // when SetEnabledExtensionImes happens later. |
| 373 return !InputMethodIsActivated(input_method_id) && | 425 return !InputMethodIsActivated(input_method_id) && |
| 374 extension_ime_util::IsExtensionIME(input_method_id); | 426 extension_ime_util::IsExtensionIME(input_method_id); |
| (...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 775 } | 827 } |
| 776 | 828 |
| 777 InputMethodManagerImpl::InputMethodManagerImpl( | 829 InputMethodManagerImpl::InputMethodManagerImpl( |
| 778 scoped_ptr<InputMethodDelegate> delegate, | 830 scoped_ptr<InputMethodDelegate> delegate, |
| 779 bool enable_extension_loading) | 831 bool enable_extension_loading) |
| 780 : delegate_(delegate.Pass()), | 832 : delegate_(delegate.Pass()), |
| 781 ui_session_(STATE_LOGIN_SCREEN), | 833 ui_session_(STATE_LOGIN_SCREEN), |
| 782 state_(NULL), | 834 state_(NULL), |
| 783 util_(delegate_.get()), | 835 util_(delegate_.get()), |
| 784 component_extension_ime_manager_(new ComponentExtensionIMEManager()), | 836 component_extension_ime_manager_(new ComponentExtensionIMEManager()), |
| 785 enable_extension_loading_(enable_extension_loading) { | 837 enable_extension_loading_(enable_extension_loading), |
| 838 stat_id_histogram_(NULL) { | |
| 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; | |
| 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) { | |
| 867 int key = i->first * 100 + j; | |
| 868 stat_id_map_[i->second[j]] = key; | |
| 869 stat_id_custom_ranges.push_back(key); | |
| 870 stat_id_custom_ranges.push_back(key + 1); | |
| 871 } | |
| 872 } | |
| 873 stat_id_histogram_ = base::CustomHistogram::FactoryGet( | |
| 874 "InputMethod.ID", stat_id_custom_ranges, | |
| 875 base::HistogramBase::kUmaTargetedHistogramFlag); | |
|
Ilya Sherman
2014/09/16 00:00:28
Hmm, why do you capture this reference, rather tha
Shu Chen
2014/09/16 16:36:29
Done.
| |
| 797 } | 876 } |
| 798 | 877 |
| 799 InputMethodManagerImpl::~InputMethodManagerImpl() { | 878 InputMethodManagerImpl::~InputMethodManagerImpl() { |
| 800 if (candidate_window_controller_.get()) | 879 if (candidate_window_controller_.get()) |
| 801 candidate_window_controller_->RemoveObserver(this); | 880 candidate_window_controller_->RemoveObserver(this); |
| 802 } | 881 } |
| 803 | 882 |
| 883 void InputMethodManagerImpl::RecordInputMethodUsage( | |
| 884 std::string input_method_id) { | |
| 885 UMA_HISTOGRAM_ENUMERATION("InputMethod.Category", | |
| 886 GetInputMethodCategory(input_method_id), | |
| 887 INPUT_METHOD_CATEGORY_MAX); | |
| 888 stat_id_histogram_->Add(stat_id_map_[input_method_id]); | |
| 889 } | |
| 890 | |
| 804 void InputMethodManagerImpl::AddObserver( | 891 void InputMethodManagerImpl::AddObserver( |
| 805 InputMethodManager::Observer* observer) { | 892 InputMethodManager::Observer* observer) { |
| 806 observers_.AddObserver(observer); | 893 observers_.AddObserver(observer); |
| 807 } | 894 } |
| 808 | 895 |
| 809 void InputMethodManagerImpl::AddCandidateWindowObserver( | 896 void InputMethodManagerImpl::AddCandidateWindowObserver( |
| 810 InputMethodManager::CandidateWindowObserver* observer) { | 897 InputMethodManager::CandidateWindowObserver* observer) { |
| 811 candidate_window_observers_.AddObserver(observer); | 898 candidate_window_observers_.AddObserver(observer); |
| 812 } | 899 } |
| 813 | 900 |
| (...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1055 if (candidate_window_controller_.get()) | 1142 if (candidate_window_controller_.get()) |
| 1056 return; | 1143 return; |
| 1057 | 1144 |
| 1058 candidate_window_controller_.reset( | 1145 candidate_window_controller_.reset( |
| 1059 CandidateWindowController::CreateCandidateWindowController()); | 1146 CandidateWindowController::CreateCandidateWindowController()); |
| 1060 candidate_window_controller_->AddObserver(this); | 1147 candidate_window_controller_->AddObserver(this); |
| 1061 } | 1148 } |
| 1062 | 1149 |
| 1063 } // namespace input_method | 1150 } // namespace input_method |
| 1064 } // namespace chromeos | 1151 } // namespace chromeos |
| OLD | NEW |