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 |