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 |