Home | History | Annotate | Download | only in spellchecker
      1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "chrome/browser/spellchecker/spellcheck_host_metrics.h"
      6 
      7 #include "base/md5.h"
      8 #include "base/metrics/histogram.h"
      9 
     10 SpellCheckHostMetrics::SpellCheckHostMetrics()
     11     : misspelled_word_count_(0),
     12       last_misspelled_word_count_(-1),
     13       spellchecked_word_count_(0),
     14       last_spellchecked_word_count_(-1),
     15       suggestion_show_count_(0),
     16       last_suggestion_show_count_(-1),
     17       replaced_word_count_(0),
     18       last_replaced_word_count_(-1),
     19       last_unique_word_count_(-1),
     20       start_time_(base::TimeTicks::Now()) {
     21   const uint64 kHistogramTimerDurationInMinutes = 30;
     22   recording_timer_.Start(FROM_HERE,
     23       base::TimeDelta::FromMinutes(kHistogramTimerDurationInMinutes),
     24       this, &SpellCheckHostMetrics::OnHistogramTimerExpired);
     25   RecordWordCounts();
     26 }
     27 
     28 SpellCheckHostMetrics::~SpellCheckHostMetrics() {
     29 }
     30 
     31 // static
     32 void SpellCheckHostMetrics::RecordCustomWordCountStats(size_t count) {
     33   UMA_HISTOGRAM_COUNTS("SpellCheck.CustomWords", count);
     34 }
     35 
     36 void SpellCheckHostMetrics::RecordEnabledStats(bool enabled) {
     37   UMA_HISTOGRAM_BOOLEAN("SpellCheck.Enabled", enabled);
     38   // Because SpellCheckHost is instantiated lazily, the size of
     39   // custom dictionary is unknown at this time. We mark it as -1 and
     40   // record actual value later. See SpellCheckHost for more detail.
     41   if (enabled)
     42     RecordCustomWordCountStats(-1);
     43 }
     44 
     45 void SpellCheckHostMetrics::RecordCheckedWordStats(const base::string16& word,
     46                                                    bool misspell) {
     47   spellchecked_word_count_++;
     48   if (misspell) {
     49     misspelled_word_count_++;
     50     // If an user misspelled, that user should be counted as a part of
     51     // the population.  So we ensure to instantiate the histogram
     52     // entries here at the first time.
     53     if (misspelled_word_count_ == 1)
     54       RecordReplacedWordStats(0);
     55   }
     56 
     57   int percentage = (100 * misspelled_word_count_) / spellchecked_word_count_;
     58   UMA_HISTOGRAM_PERCENTAGE("SpellCheck.MisspellRatio", percentage);
     59 
     60   // Collects actual number of checked words, excluding duplication.
     61   base::MD5Digest digest;
     62   base::MD5Sum(reinterpret_cast<const unsigned char*>(word.c_str()),
     63          word.size() * sizeof(base::char16), &digest);
     64   checked_word_hashes_.insert(base::MD5DigestToBase16(digest));
     65 
     66   RecordWordCounts();
     67 }
     68 
     69 void SpellCheckHostMetrics::OnHistogramTimerExpired() {
     70   if (0 < spellchecked_word_count_) {
     71     // Collects word checking rate, which is represented
     72     // as a word count per hour.
     73     base::TimeDelta since_start = base::TimeTicks::Now() - start_time_;
     74     // This shouldn't happen since OnHistogramTimerExpired() is called on
     75     // a 30 minute interval. If the time was 0 we will end up dividing by zero.
     76     CHECK_NE(0, since_start.InSeconds());
     77     size_t checked_words_per_hour = spellchecked_word_count_ *
     78         base::TimeDelta::FromHours(1).InSeconds() / since_start.InSeconds();
     79     UMA_HISTOGRAM_COUNTS("SpellCheck.CheckedWordsPerHour",
     80                          checked_words_per_hour);
     81   }
     82 }
     83 
     84 void SpellCheckHostMetrics::RecordDictionaryCorruptionStats(bool corrupted) {
     85   UMA_HISTOGRAM_BOOLEAN("SpellCheck.DictionaryCorrupted", corrupted);
     86 }
     87 
     88 void SpellCheckHostMetrics::RecordSuggestionStats(int delta) {
     89   suggestion_show_count_ += delta;
     90   // RecordReplacedWordStats() Calls RecordWordCounts() eventually.
     91   RecordReplacedWordStats(0);
     92 }
     93 
     94 void SpellCheckHostMetrics::RecordReplacedWordStats(int delta) {
     95   replaced_word_count_ += delta;
     96 
     97   if (misspelled_word_count_) {
     98     // zero |misspelled_word_count_| is possible when an extension
     99     // gives the misspelling, which is not recorded as a part of this
    100     // metrics.
    101     int percentage = (100 * replaced_word_count_) / misspelled_word_count_;
    102     UMA_HISTOGRAM_PERCENTAGE("SpellCheck.ReplaceRatio", percentage);
    103   }
    104 
    105   if (suggestion_show_count_) {
    106     int percentage = (100 * replaced_word_count_) / suggestion_show_count_;
    107     UMA_HISTOGRAM_PERCENTAGE("SpellCheck.SuggestionHitRatio", percentage);
    108   }
    109 
    110   RecordWordCounts();
    111 }
    112 
    113 void SpellCheckHostMetrics::RecordWordCounts() {
    114   if (spellchecked_word_count_ != last_spellchecked_word_count_) {
    115     DCHECK(spellchecked_word_count_ > last_spellchecked_word_count_);
    116     UMA_HISTOGRAM_COUNTS("SpellCheck.CheckedWords", spellchecked_word_count_);
    117     last_spellchecked_word_count_ = spellchecked_word_count_;
    118   }
    119 
    120   if (misspelled_word_count_ != last_misspelled_word_count_) {
    121     DCHECK(misspelled_word_count_ > last_misspelled_word_count_);
    122     UMA_HISTOGRAM_COUNTS("SpellCheck.MisspelledWords", misspelled_word_count_);
    123     last_misspelled_word_count_ = misspelled_word_count_;
    124   }
    125 
    126   if (replaced_word_count_ != last_replaced_word_count_) {
    127     DCHECK(replaced_word_count_ > last_replaced_word_count_);
    128     UMA_HISTOGRAM_COUNTS("SpellCheck.ReplacedWords", replaced_word_count_);
    129     last_replaced_word_count_ = replaced_word_count_;
    130   }
    131 
    132   if (((int)checked_word_hashes_.size()) != last_unique_word_count_) {
    133     DCHECK((int)checked_word_hashes_.size() > last_unique_word_count_);
    134     UMA_HISTOGRAM_COUNTS("SpellCheck.UniqueWords", checked_word_hashes_.size());
    135     last_unique_word_count_ = checked_word_hashes_.size();
    136   }
    137 
    138   if (suggestion_show_count_ != last_suggestion_show_count_) {
    139     DCHECK(suggestion_show_count_ > last_suggestion_show_count_);
    140     UMA_HISTOGRAM_COUNTS("SpellCheck.ShownSuggestions", suggestion_show_count_);
    141     last_suggestion_show_count_ = suggestion_show_count_;
    142   }
    143 }
    144 
    145 void SpellCheckHostMetrics::RecordSpellingServiceStats(bool enabled) {
    146   UMA_HISTOGRAM_BOOLEAN("SpellCheck.SpellingService.Enabled", enabled);
    147 }
    148