diff options
author | shuchen <shuchen@chromium.org> | 2014-09-17 22:03:07 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-09-18 05:03:18 +0000 |
commit | 0d95894f4e846d7352d9813cd34f43efdb6e1e4e (patch) | |
tree | 909f13378497177e9b5b0cc59f49cbf4356c5ced /chrome | |
parent | 9e5e3f4060f759384d224a44c41d3f4a328b86d8 (diff) | |
download | chromium_src-0d95894f4e846d7352d9813cd34f43efdb6e1e4e.zip chromium_src-0d95894f4e846d7352d9813cd34f43efdb6e1e4e.tar.gz chromium_src-0d95894f4e846d7352d9813cd34f43efdb6e1e4e.tar.bz2 |
Updates the histograms for IMF and IMEs according to the new design.
BUG=367631
TEST=Verified on linux_chromeos.
Review URL: https://codereview.chromium.org/561223002
Cr-Commit-Position: refs/heads/master@{#295417}
Diffstat (limited to 'chrome')
5 files changed, 119 insertions, 88 deletions
diff --git a/chrome/browser/chromeos/input_method/input_method_engine.cc b/chrome/browser/chromeos/input_method/input_method_engine.cc index ddd3507..00c5b4e 100644 --- a/chrome/browser/chromeos/input_method/input_method_engine.cc +++ b/chrome/browser/chromeos/input_method/input_method_engine.cc @@ -162,8 +162,6 @@ InputMethodEngine::InputMethodEngine() } InputMethodEngine::~InputMethodEngine() { - if (start_time_.ToInternalValue()) - RecordHistogram("WorkingTime", (end_time_ - start_time_).InSeconds()); } void InputMethodEngine::Initialize( @@ -176,15 +174,6 @@ void InputMethodEngine::Initialize( extension_id_ = extension_id; } -void InputMethodEngine::RecordHistogram(const char* name, int count) { - std::string histo_name = base::StringPrintf( - "InputMethod.%s.%s", name, active_component_id_.c_str()); - base::HistogramBase* counter = base::Histogram::FactoryGet( - histo_name, 0, 1000000, 50, base::HistogramBase::kNoFlags); - if (counter) - counter->Add(count); -} - const std::string& InputMethodEngine::GetActiveComponentId() const { return active_component_id_; } @@ -270,13 +259,12 @@ bool InputMethodEngine::CommitText(int context_id, const char* text, IMEBridge::Get()->GetInputContextHandler()->CommitText(text); - // Records times for using input method. - if (!start_time_.ToInternalValue()) - start_time_ = base::Time::Now(); - end_time_ = base::Time::Now(); - // Records histograms for counts of commits and committed characters. - RecordHistogram("Commit", 1); - RecordHistogram("CommitCharacter", GetUtf8StringLength(text)); + // Records histograms for committed characters. + if (!composition_text_->text().empty()) { + size_t len = GetUtf8StringLength(text); + UMA_HISTOGRAM_CUSTOM_COUNTS("InputMethod.CommitLength", + len, 1, 25, 25); + } return true; } @@ -326,6 +314,7 @@ bool InputMethodEngine::SendKeyEvents( if (details.dispatcher_destroyed) break; } + return true; } @@ -573,18 +562,11 @@ void InputMethodEngine::Enable(const std::string& component_id) { FocusIn(IMEEngineHandlerInterface::InputContext( current_input_type_, ui::TEXT_INPUT_MODE_DEFAULT)); EnableInputView(); - - start_time_ = base::Time(); - end_time_ = base::Time(); - RecordHistogram("Enable", 1); } void InputMethodEngine::Disable() { active_component_id_.clear(); observer_->OnDeactivated(active_component_id_); - - if (start_time_.ToInternalValue()) - RecordHistogram("WorkingTime", (end_time_ - start_time_).InSeconds()); } void InputMethodEngine::PropertyActivate(const std::string& property_name) { diff --git a/chrome/browser/chromeos/input_method/input_method_engine.h b/chrome/browser/chromeos/input_method/input_method_engine.h index 9aa6364..671d09e 100644 --- a/chrome/browser/chromeos/input_method/input_method_engine.h +++ b/chrome/browser/chromeos/input_method/input_method_engine.h @@ -91,9 +91,9 @@ class InputMethodEngine : public InputMethodEngineInterface { uint32 anchor_pos) OVERRIDE; virtual void HideInputView() OVERRIDE; - private: - void RecordHistogram(const char* name, int count); + int GetCotextIdForTesting() { return context_id_; } + private: // Converts MenuItem to InputMethodMenuItem. void MenuItemToProperty(const MenuItem& item, ash::ime::InputMethodMenuItem* property); @@ -140,10 +140,6 @@ class InputMethodEngine : public InputMethodEngineInterface { // Used with SendKeyEvents and ProcessKeyEvent to check if the key event // sent to ProcessKeyEvent is sent by SendKeyEvents. const ui::KeyEvent* sent_key_event_; - - // The start & end time of using this input method. This is for UMA. - base::Time start_time_; - base::Time end_time_; }; } // namespace chromeos diff --git a/chrome/browser/chromeos/input_method/input_method_engine_unittest.cc b/chrome/browser/chromeos/input_method/input_method_engine_unittest.cc index 31ce003..5863571 100644 --- a/chrome/browser/chromeos/input_method/input_method_engine_unittest.cc +++ b/chrome/browser/chromeos/input_method/input_method_engine_unittest.cc @@ -6,6 +6,7 @@ #include "base/metrics/histogram.h" #include "base/metrics/histogram_samples.h" #include "base/metrics/statistics_recorder.h" +#include "base/test/histogram_tester.h" #include "chrome/browser/chromeos/input_method/input_method_configuration.h" #include "chrome/browser/chromeos/input_method/input_method_engine.h" #include "chrome/browser/chromeos/input_method/input_method_engine_interface.h" @@ -24,19 +25,6 @@ const char kTestExtensionId[] = "mppnpdlheglhdfmldimlhpnegondlapf"; const char kTestExtensionId2[] = "dmpipdbjkoajgdeppkffbjhngfckdloi"; const char kTestImeComponentId[] = "test_engine_id"; -const char* kHistogramNames[] = { - "InputMethod.Enable.test_engine_id", "InputMethod.Commit.test_engine_id", - "InputMethod.CommitCharacter.test_engine_id", -}; - -scoped_ptr<base::HistogramSamples> GetHistogramSamples( - const char* histogram_name) { - base::HistogramBase* histogram = - base::StatisticsRecorder::FindHistogram(histogram_name); - EXPECT_NE(static_cast<base::HistogramBase*>(NULL), histogram); - return histogram->SnapshotSamples().Pass(); -} - enum CallsBitmap { NONE = 0U, ACTIVATE = 1U, @@ -132,18 +120,6 @@ class InputMethodEngineTest : public testing::Test { mock_ime_input_context_handler_.reset(new MockIMEInputContextHandler()); IMEBridge::Get()->SetInputContextHandler( mock_ime_input_context_handler_.get()); - - base::StatisticsRecorder::Initialize(); - - for (size_t i = 0; i < arraysize(kHistogramNames); i++) { - base::Histogram::FactoryGet( - kHistogramNames[i], 0, 1000000, 50, base::HistogramBase::kNoFlags) - ->Add(0); - initial_histogram_samples_[i] = - GetHistogramSamples(kHistogramNames[i]).Pass(); - initial_histogram_samples_map_[kHistogramNames[i]] = - initial_histogram_samples_[i].get(); - } } virtual ~InputMethodEngineTest() { IMEBridge::Get()->SetInputContextHandler(NULL); @@ -152,25 +128,6 @@ class InputMethodEngineTest : public testing::Test { } protected: - scoped_ptr<base::HistogramSamples> GetHistogramSamplesDelta( - const char* histogram_name) { - scoped_ptr<base::HistogramSamples> delta_samples( - GetHistogramSamples(histogram_name)); - delta_samples->Subtract(*initial_histogram_samples_map_[histogram_name]); - - return delta_samples.Pass(); - } - - void ExpectNewSample(const char* histogram_name, - base::HistogramBase::Sample sample, - int total_count, - int sample_count) { - scoped_ptr<base::HistogramSamples> delta_samples( - GetHistogramSamplesDelta(histogram_name)); - EXPECT_EQ(total_count, delta_samples->TotalCount()); - EXPECT_EQ(sample_count, delta_samples->GetCount(sample)); - } - void CreateEngine(bool whitelisted) { engine_.reset(new InputMethodEngine()); observer_ = new TestObserver(); @@ -194,10 +151,6 @@ class InputMethodEngineTest : public testing::Test { GURL options_page_; GURL input_view_; - scoped_ptr<base::HistogramSamples> - initial_histogram_samples_[arraysize(kHistogramNames)]; - std::map<std::string, base::HistogramSamples*> initial_histogram_samples_map_; - scoped_ptr<MockIMEInputContextHandler> mock_ime_input_context_handler_; private: @@ -280,15 +233,20 @@ TEST_F(InputMethodEngineTest, TestHistograms) { CreateEngine(true); FocusIn(ui::TEXT_INPUT_TYPE_TEXT); engine_->Enable(kTestImeComponentId); + std::vector<InputMethodEngineInterface::SegmentInfo> segments; + engine_->SetComposition( + engine_->GetCotextIdForTesting(), "test", 0, 0, 0, segments, NULL); std::string error; - ExpectNewSample("InputMethod.Enable.test_engine_id", 1, 1, 1); + base::HistogramTester histograms; engine_->CommitText(1, "input", &error); - engine_->CommitText(1, "入力", &error); - engine_->CommitText(1, "input入力", &error); - ExpectNewSample("InputMethod.Commit.test_engine_id", 1, 3, 3); - ExpectNewSample("InputMethod.CommitCharacter.test_engine_id", 5, 3, 1); - ExpectNewSample("InputMethod.CommitCharacter.test_engine_id", 2, 3, 1); - ExpectNewSample("InputMethod.CommitCharacter.test_engine_id", 7, 3, 1); + engine_->CommitText(1, + "\xE5\x85\xA5\xE5\x8A\x9B", // 2 UTF-8 characters + &error); + engine_->CommitText(1, "input\xE5\x85\xA5\xE5\x8A\x9B", &error); + histograms.ExpectTotalCount("InputMethod.CommitLength", 3); + histograms.ExpectBucketCount("InputMethod.CommitLength", 5, 1); + histograms.ExpectBucketCount("InputMethod.CommitLength", 2, 1); + histograms.ExpectBucketCount("InputMethod.CommitLength", 7, 1); } } // namespace input_method diff --git a/chrome/browser/chromeos/input_method/input_method_manager_impl.cc b/chrome/browser/chromeos/input_method/input_method_manager_impl.cc index 3c7c0c7..9b1bbe3 100644 --- a/chrome/browser/chromeos/input_method/input_method_manager_impl.cc +++ b/chrome/browser/chromeos/input_method/input_method_manager_impl.cc @@ -14,6 +14,8 @@ #include "base/bind.h" #include "base/location.h" #include "base/memory/scoped_ptr.h" +#include "base/metrics/histogram.h" +#include "base/metrics/sparse_histogram.h" #include "base/prefs/pref_service.h" #include "base/strings/string_split.h" #include "base/strings/string_util.h" @@ -50,6 +52,51 @@ bool Contains(const std::vector<std::string>& container, container.end(); } +enum InputMethodCategory { + INPUT_METHOD_CATEGORY_UNKNOWN = 0, + INPUT_METHOD_CATEGORY_XKB, // XKB input methods + INPUT_METHOD_CATEGORY_ZH, // Chinese input methods + INPUT_METHOD_CATEGORY_JA, // Japanese input methods + INPUT_METHOD_CATEGORY_KO, // Korean input methods + INPUT_METHOD_CATEGORY_M17N, // Multilingualization input methods + INPUT_METHOD_CATEGORY_T13N, // Transliteration input methods + INPUT_METHOD_CATEGORY_MAX +}; + +InputMethodCategory GetInputMethodCategory(const std::string& input_method_id, + char* first_char = NULL) { + const std::string component_id = + extension_ime_util::GetComponentIDByInputMethodID(input_method_id); + InputMethodCategory category = INPUT_METHOD_CATEGORY_UNKNOWN; + char ch = 0; + if (StartsWithASCII(component_id, "xkb:", true)) { + ch = component_id[4]; + category = INPUT_METHOD_CATEGORY_XKB; + } else if (StartsWithASCII(component_id, "zh-", true)) { + size_t pos = component_id.find("-t-i0-"); + if (pos > 0) + pos += 6; + ch = component_id[pos]; + category = INPUT_METHOD_CATEGORY_ZH; + } else if (StartsWithASCII(component_id, "nacl_mozc_", true)) { + ch = component_id[10]; + category = INPUT_METHOD_CATEGORY_JA; + } else if (StartsWithASCII(component_id, "hangul_", true)) { + ch = component_id[7]; + category = INPUT_METHOD_CATEGORY_KO; + } else if (StartsWithASCII(component_id, "vkd_", true)) { + ch = component_id[4]; + category = INPUT_METHOD_CATEGORY_M17N; + } else if (component_id.find("-t-i0-") > 0) { + ch = component_id[0]; + category = INPUT_METHOD_CATEGORY_T13N; + } + + if (first_char) + *first_char = ch; + return category; +} + } // namespace // ------------------------ InputMethodManagerImpl::StateImpl @@ -329,6 +376,11 @@ bool InputMethodManagerImpl::StateImpl::ReplaceEnabledInputMethods( // If |current_input_method| is no longer in |active_input_method_ids|, // ChangeInputMethod() picks the first one in |active_input_method_ids|. ChangeInputMethod(current_input_method.id(), false); + + // Record histogram for active input method count. + UMA_HISTOGRAM_COUNTS("InputMethod.ActiveCount", + active_input_method_ids.size()); + return true; } @@ -362,6 +414,7 @@ void InputMethodManagerImpl::StateImpl::ChangeInputMethod( // TODO(komatsu): Revisit if this is neccessary. if (IsActive()) manager_->ChangeInputMethodInternal(*descriptor, show_message, notify_menu); + manager_->RecordInputMethodUsage(current_input_method.id()); } bool InputMethodManagerImpl::StateImpl::MethodAwaitsExtensionLoad( @@ -793,8 +846,28 @@ InputMethodManagerImpl::InputMethodManagerImpl( scoped_ptr<ComponentExtensionIMEManagerDelegate> comp_delegate( new ComponentExtensionIMEManagerImpl()); component_extension_ime_manager_->Initialize(comp_delegate.Pass()); - util_.ResetInputMethods( - component_extension_ime_manager_->GetAllIMEAsInputMethodDescriptor()); + const InputMethodDescriptors& descriptors = + component_extension_ime_manager_->GetAllIMEAsInputMethodDescriptor(); + util_.ResetInputMethods(descriptors); + + // Initializes the stat id map. + std::map<int, std::vector<std::string> > buckets; + for (InputMethodDescriptors::const_iterator it = descriptors.begin(); + it != descriptors.end(); ++it) { + char first_char; + int cat_id = static_cast<int>( + GetInputMethodCategory(it->id(), &first_char)); + int key = cat_id * 1000 + first_char; + buckets[key].push_back(it->id()); + } + for (std::map<int, std::vector<std::string>>::iterator i = + buckets.begin(); i != buckets.end(); ++i) { + std::sort(i->second.begin(), i->second.end()); + for (size_t j = 0; j < i->second.size() && j < 100; ++j) { + int key = i->first * 100 + j; + stat_id_map_[i->second[j]] = key; + } + } } InputMethodManagerImpl::~InputMethodManagerImpl() { @@ -802,6 +875,15 @@ InputMethodManagerImpl::~InputMethodManagerImpl() { candidate_window_controller_->RemoveObserver(this); } +void InputMethodManagerImpl::RecordInputMethodUsage( + std::string input_method_id) { + UMA_HISTOGRAM_ENUMERATION("InputMethod.Category", + GetInputMethodCategory(input_method_id), + INPUT_METHOD_CATEGORY_MAX); + UMA_HISTOGRAM_SPARSE_SLOWLY("InputMethod.ID", + stat_id_map_[input_method_id]); +} + void InputMethodManagerImpl::AddObserver( InputMethodManager::Observer* observer) { observers_.AddObserver(observer); diff --git a/chrome/browser/chromeos/input_method/input_method_manager_impl.h b/chrome/browser/chromeos/input_method/input_method_manager_impl.h index 1aa0123..8864000 100644 --- a/chrome/browser/chromeos/input_method/input_method_manager_impl.h +++ b/chrome/browser/chromeos/input_method/input_method_manager_impl.h @@ -222,6 +222,9 @@ class InputMethodManagerImpl : public InputMethodManager, // If state is active, active input method is updated. void ReconfigureIMFramework(StateImpl* state); + // Record input method usage histograms. + void RecordInputMethodUsage(std::string input_method_id); + scoped_ptr<InputMethodDelegate> delegate_; // The current UI session status. @@ -256,6 +259,16 @@ class InputMethodManagerImpl : public InputMethodManager, typedef std::map<std::string, InputMethodEngineInterface*> EngineMap; EngineMap engine_map_; + // The map from input method id to the input method stat id. + // The stat id has the format: <category#><first char after prefix><index> + // For example, Chinese Simplified Pinyin IME has the stat id: + // 2,'p',1 -> 211201 + // 2 means it in INPUT_METHOD_CATEGORY_ZH; + // 112 means the first char after prefix is 'p' of 'pinyin'; + // 01 means it's the second pinyin as the first pinyin is for Traditional + // Chinese Pinyin IME. Note "zh-hant-t-i0-pinyin" < "zh-t-i0-pinyin". + std::map<std::string, int> stat_id_map_; + DISALLOW_COPY_AND_ASSIGN(InputMethodManagerImpl); }; |