diff options
author | shuchen@chromium.org <shuchen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-09 12:44:13 +0000 |
---|---|---|
committer | shuchen@chromium.org <shuchen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-09 12:44:13 +0000 |
commit | 6040a4668403c6f3ad4959a3fd67dee29ba1f4b7 (patch) | |
tree | 68b26e9d838073014d771952fb4bbbc8610c64d5 | |
parent | 5a263ba64cb1f2270764f02531965ad2ad4146ca (diff) | |
download | chromium_src-6040a4668403c6f3ad4959a3fd67dee29ba1f4b7.zip chromium_src-6040a4668403c6f3ad4959a3fd67dee29ba1f4b7.tar.gz chromium_src-6040a4668403c6f3ad4959a3fd67dee29ba1f4b7.tar.bz2 |
[IME] Adds these histograms in IMF. 1) Count of IME is activated/deactivated 2) Count of commits with each IME 3) Count of committed characters with each IME 4) Time duration of using each IME
BUG=367631
TEST=None
Review URL: https://codereview.chromium.org/252813004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@269250 0039d316-1c4b-4281-b951-d872f2087c98
3 files changed, 122 insertions, 0 deletions
diff --git a/chrome/browser/chromeos/input_method/input_method_engine.cc b/chrome/browser/chromeos/input_method/input_method_engine.cc index aaa9539..215e9bd 100644 --- a/chrome/browser/chromeos/input_method/input_method_engine.cc +++ b/chrome/browser/chromeos/input_method/input_method_engine.cc @@ -19,8 +19,10 @@ #include "ash/shell.h" #include "base/logging.h" #include "base/memory/scoped_ptr.h" +#include "base/metrics/histogram.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" +#include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" #include "chromeos/ime/component_extension_ime_manager.h" #include "chromeos/ime/composition_text.h" @@ -55,6 +57,19 @@ void UpdateComposition(const CompositionText& composition_text, composition_text, cursor_pos, is_visible); } +// Returns the length of characters of a UTF-8 string with unknown string +// length. Cannot apply faster algorithm to count characters in an utf-8 +// string without knowing the string length, so just does a full scan. +size_t GetUtf8StringLength(const char* s) { + size_t ret = 0; + while (*s) { + if ((*s & 0xC0) != 0x80) + ret++; + ++s; + } + return ret; +} + } // namespace InputMethodEngine::InputMethodEngine() @@ -69,6 +84,8 @@ InputMethodEngine::InputMethodEngine() sent_key_event_(NULL) {} InputMethodEngine::~InputMethodEngine() { + if (start_time_.ToInternalValue()) + RecordHistogram("WorkingTime", (end_time_ - start_time_).InSeconds()); input_method::InputMethodManager::Get()->RemoveInputMethodExtension(imm_id_); } @@ -122,6 +139,15 @@ const input_method::InputMethodDescriptor& InputMethodEngine::GetDescriptor() return descriptor_; } +void InputMethodEngine::RecordHistogram(const char* name, int count) { + std::string histo_name = + base::StringPrintf("InputMethod.%s.%s", name, engine_id_.c_str()); + base::HistogramBase* counter = base::Histogram::FactoryGet( + histo_name, 0, 1000000, 50, base::HistogramBase::kNoFlags); + if (counter) + counter->Add(count); +} + void InputMethodEngine::NotifyImeReady() { input_method::InputMethodManager* manager = input_method::InputMethodManager::Get(); @@ -209,6 +235,14 @@ 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)); return true; } @@ -525,11 +559,18 @@ void InputMethodEngine::Enable() { FocusIn(IMEEngineHandlerInterface::InputContext( current_input_type_, ui::TEXT_INPUT_MODE_DEFAULT)); EnableInputView(true); + + start_time_ = base::Time(); + end_time_ = base::Time(); + RecordHistogram("Enable", 1); } void InputMethodEngine::Disable() { active_ = false; observer_->OnDeactivated(engine_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 328653d..716d136 100644 --- a/chrome/browser/chromeos/input_method/input_method_engine.h +++ b/chrome/browser/chromeos/input_method/input_method_engine.h @@ -8,6 +8,7 @@ #include <map> #include <string> #include <vector> +#include "base/time/time.h" #include "chrome/browser/chromeos/input_method/input_method_engine_interface.h" #include "chromeos/ime/input_method_descriptor.h" #include "url/gurl.h" @@ -99,6 +100,8 @@ class InputMethodEngine : public InputMethodEngineInterface { virtual void HideInputView() OVERRIDE; private: + void RecordHistogram(const char* name, int count); + // Converts MenuItem to InputMethodMenuItem. void MenuItemToProperty(const MenuItem& item, ash::ime::InputMethodMenuItem* property); @@ -157,6 +160,10 @@ 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 7a8434b..50e3be4 100644 --- a/chrome/browser/chromeos/input_method/input_method_engine_unittest.cc +++ b/chrome/browser/chromeos/input_method/input_method_engine_unittest.cc @@ -3,6 +3,9 @@ // found in the LICENSE file. #include "base/logging.h" +#include "base/metrics/histogram.h" +#include "base/metrics/histogram_samples.h" +#include "base/metrics/statistics_recorder.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" @@ -10,6 +13,7 @@ #include "chromeos/ime/extension_ime_util.h" #include "chromeos/ime/mock_component_extension_ime_manager_delegate.h" #include "testing/gtest/include/gtest/gtest.h" +#include "ui/base/ime/chromeos/mock_ime_input_context_handler.h" namespace chromeos { @@ -20,6 +24,19 @@ const char kTestExtensionId[] = "mppnpdlheglhdfmldimlhpnegondlapf"; const char kTestExtensionId2[] = "dmpipdbjkoajgdeppkffbjhngfckdloi"; const char kTestImeEngineId[] = "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, @@ -112,13 +129,48 @@ class InputMethodEngineTest : public testing::Test { layouts_.push_back("us"); InitInputMethod(); IMEBridge::Initialize(); + 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); engine_.reset(); Shutdown(); } 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(); @@ -141,12 +193,19 @@ class InputMethodEngineTest : public testing::Test { } scoped_ptr<InputMethodEngine> engine_; + TestObserver* observer_; std::vector<std::string> languages_; std::vector<std::string> layouts_; 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: DISALLOW_COPY_AND_ASSIGN(InputMethodEngineTest); }; @@ -223,5 +282,20 @@ TEST_F(InputMethodEngineTest, TestSwitching_Password_Whitelisted) { EXPECT_EQ(DEACTIVATED, observer_->GetCallsBitmapAndReset()); } +TEST_F(InputMethodEngineTest, TestHistograms) { + CreateEngine(true); + FocusIn(ui::TEXT_INPUT_TYPE_TEXT); + engine_->Enable(); + std::string error; + ExpectNewSample("InputMethod.Enable.test_engine_id", 1, 1, 1); + 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); +} + } // namespace input_method } // namespace chromeos |