summaryrefslogtreecommitdiffstats
path: root/components
diff options
context:
space:
mode:
authordroger@chromium.org <droger@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-01-09 19:05:05 +0000
committerdroger@chromium.org <droger@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-01-09 19:05:05 +0000
commit3f3a65fe54ba1ffad797a44401ffd42d9de9ffce (patch)
treeb4ef7b030c6c6a181dd222c55d108b18be42e053 /components
parentcaace87499af099ae2bc43d03eb9444200bee2e9 (diff)
downloadchromium_src-3f3a65fe54ba1ffad797a44401ffd42d9de9ffce.zip
chromium_src-3f3a65fe54ba1ffad797a44401ffd42d9de9ffce.tar.gz
chromium_src-3f3a65fe54ba1ffad797a44401ffd42d9de9ffce.tar.bz2
Move LanguageUsageMetrics and TranslateBrowserMetrics to components
LanguageUsageMetrics is moved to its own component because it is used both in the translate component and directly in the browser. TranslateBrowserMetrics is moved to the translate component. BUG=331509 TBR=jochen Review URL: https://codereview.chromium.org/131203002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@243946 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'components')
-rw-r--r--components/components.gyp1
-rw-r--r--components/components_tests.gyp7
-rw-r--r--components/language_usage_metrics.gypi22
-rw-r--r--components/language_usage_metrics/OWNERS3
-rw-r--r--components/language_usage_metrics/language_usage_metrics.cc75
-rw-r--r--components/language_usage_metrics/language_usage_metrics.h53
-rw-r--r--components/language_usage_metrics/language_usage_metrics_unittest.cc107
-rw-r--r--components/translate.gypi3
-rw-r--r--components/translate/DEPS6
-rw-r--r--components/translate/core/browser/translate_browser_metrics.cc94
-rw-r--r--components/translate/core/browser/translate_browser_metrics.h64
-rw-r--r--components/translate/core/browser/translate_browser_metrics_unittest.cc187
12 files changed, 621 insertions, 1 deletions
diff --git a/components/components.gyp b/components/components.gyp
index 89488a1..341d120 100644
--- a/components/components.gyp
+++ b/components/components.gyp
@@ -15,6 +15,7 @@
'breakpad.gypi',
'dom_distiller.gypi',
'json_schema.gypi',
+ 'language_usage_metrics.gypi',
'navigation_metrics.gypi',
'onc.gypi',
'policy.gypi',
diff --git a/components/components_tests.gyp b/components/components_tests.gyp
index 7dca5d6..d16e68b 100644
--- a/components/components_tests.gyp
+++ b/components/components_tests.gyp
@@ -41,6 +41,7 @@
'json_schema/json_schema_validator_unittest.cc',
'json_schema/json_schema_validator_unittest_base.cc',
'json_schema/json_schema_validator_unittest_base.h',
+ 'language_usage_metrics/language_usage_metrics_unittest.cc',
'navigation_interception/intercept_navigation_resource_throttle_unittest.cc',
'precache/content/precache_manager_unittest.cc',
'precache/core/precache_database_unittest.cc',
@@ -49,6 +50,7 @@
'sessions/serialized_navigation_entry_unittest.cc',
'signin/core/webdata/token_service_table_unittest.cc',
'test/run_all_unittests.cc',
+ 'translate/core/browser/translate_browser_metrics_unittest.cc',
'translate/core/common/translate_metrics_unittest.cc',
'translate/core/common/translate_util_unittest.cc',
'translate/language_detection/language_detection_util_unittest.cc',
@@ -102,6 +104,9 @@
# Dependencies of json_schema
'components.gyp:json_schema',
+ # Dependencies of language_usage_metrics
+ 'components.gyp:language_usage_metrics',
+
# Dependencies of precache/core
'components.gyp:precache_core',
@@ -109,6 +114,7 @@
'components.gyp:signin_core',
# Dependencies of translate.
+ 'components.gyp:translate_core_browser',
'components.gyp:translate_core_common',
'components.gyp:translate_language_detection',
@@ -157,6 +163,7 @@
['include', '^auto_login_parser/'],
['include', '^autofill/'],
['include', '^dom_distiller/'],
+ ['include', '^language_usage_metrics/'],
['include', '^precache/core/'],
['include', '^signin/'],
['include', '^translate/'],
diff --git a/components/language_usage_metrics.gypi b/components/language_usage_metrics.gypi
new file mode 100644
index 0000000..e150a1bb
--- /dev/null
+++ b/components/language_usage_metrics.gypi
@@ -0,0 +1,22 @@
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+{
+ 'targets': [
+ {
+ 'target_name': 'language_usage_metrics',
+ 'type': 'static_library',
+ 'dependencies': [
+ '../base/base.gyp:base',
+ ],
+ 'include_dirs': [
+ '..',
+ ],
+ 'sources': [
+ 'language_usage_metrics/language_usage_metrics.cc',
+ 'language_usage_metrics/language_usage_metrics.h',
+ ],
+ },
+ ],
+}
diff --git a/components/language_usage_metrics/OWNERS b/components/language_usage_metrics/OWNERS
new file mode 100644
index 0000000..a214ab1
--- /dev/null
+++ b/components/language_usage_metrics/OWNERS
@@ -0,0 +1,3 @@
+hajimehoshi@chromium.org
+mad@chromium.org
+toyoshim@chromium.org
diff --git a/components/language_usage_metrics/language_usage_metrics.cc b/components/language_usage_metrics/language_usage_metrics.cc
new file mode 100644
index 0000000..adb91c9
--- /dev/null
+++ b/components/language_usage_metrics/language_usage_metrics.cc
@@ -0,0 +1,75 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/language_usage_metrics/language_usage_metrics.h"
+
+#include <algorithm>
+
+#include "base/metrics/sparse_histogram.h"
+#include "base/strings/string_tokenizer.h"
+#include "base/strings/string_util.h"
+
+namespace {
+void RecordAcceptLanguage(int language_code) {
+ UMA_HISTOGRAM_SPARSE_SLOWLY("LanguageUsage.AcceptLanguage",
+ language_code);
+}
+} // namespace
+
+namespace language_usage_metrics {
+
+// static
+void LanguageUsageMetrics::RecordAcceptLanguages(
+ const std::string& accept_languages) {
+ std::set<int> languages;
+ ParseAcceptLanguages(accept_languages, &languages);
+ std::for_each(languages.begin(), languages.end(), RecordAcceptLanguage);
+}
+
+// static
+void LanguageUsageMetrics::RecordApplicationLanguage(
+ const std::string& application_locale) {
+ const int language_code = ToLanguageCode(application_locale);
+ if (language_code != 0)
+ UMA_HISTOGRAM_SPARSE_SLOWLY("LanguageUsage.ApplicationLanguage",
+ language_code);
+}
+
+// static
+int LanguageUsageMetrics::ToLanguageCode(const std::string& locale) {
+ base::StringTokenizer parts(locale, "-_");
+ if (!parts.GetNext())
+ return 0;
+
+ std::string language_part = parts.token();
+ StringToLowerASCII(&language_part);
+
+ int language_code = 0;
+ for (std::string::iterator it = language_part.begin();
+ it != language_part.end(); ++it) {
+ char ch = *it;
+ if (ch < 'a' || 'z' < ch)
+ return 0;
+
+ language_code <<= 8;
+ language_code += ch;
+ }
+
+ return language_code;
+}
+
+// static
+void LanguageUsageMetrics::ParseAcceptLanguages(
+ const std::string& accept_languages,
+ std::set<int>* languages) {
+ languages->clear();
+ base::StringTokenizer locales(accept_languages, ",");
+ while (locales.GetNext()) {
+ const int language_code = ToLanguageCode(locales.token());
+ if (language_code != 0)
+ languages->insert(language_code);
+ }
+}
+
+} // namespace language_usage_metrics
diff --git a/components/language_usage_metrics/language_usage_metrics.h b/components/language_usage_metrics/language_usage_metrics.h
new file mode 100644
index 0000000..ffde58b
--- /dev/null
+++ b/components/language_usage_metrics/language_usage_metrics.h
@@ -0,0 +1,53 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_LANGUAGE_USAGE_METRICS_LANGUAGE_USAGE_METRICS_H_
+#define COMPONENTS_LANGUAGE_USAGE_METRICS_LANGUAGE_USAGE_METRICS_H_
+
+#include <set>
+#include <string>
+
+#include "base/basictypes.h"
+#include "base/gtest_prod_util.h"
+
+namespace language_usage_metrics {
+
+// Methods to record language usage as UMA histograms.
+class LanguageUsageMetrics {
+ public:
+ // Records accept languages as a UMA histogram. |accept_languages| is a
+ // case-insensitive comma-separated list of languages/locales of either xx,
+ // xx-YY, or xx_YY format where xx is iso-639 language code and YY is iso-3166
+ // country code. Country code is ignored. That is, xx and XX-YY are considered
+ // identical and recorded once.
+ static void RecordAcceptLanguages(const std::string& accept_languages);
+
+ // Records the application language as a UMA histogram. |application_locale|
+ // is a case-insensitive locale string of either xx, xx-YY, or xx_YY format.
+ // Only the language part (xx in the example) is considered.
+ static void RecordApplicationLanguage(const std::string& application_locale);
+
+ // Parses |locale| and returns the language code. Returns 0 in case of errors.
+ // The language code is calculated from two alphabets. For example, if
+ // |locale| is 'en' which represents 'English', the codes of 'e' and 'n' are
+ // 101 and 110 respectively, and the language code will be 101 * 256 + 100 =
+ // 25966.
+ // |locale| should consist of only lower-case letters. This function doesn't
+ // check whether |locale| is valid locale or not strictly.
+ static int ToLanguageCode(const std::string &locale);
+
+ private:
+ DISALLOW_IMPLICIT_CONSTRUCTORS(LanguageUsageMetrics);
+
+ // Parses |accept_languages| and returns a set of language codes in
+ // |languages|.
+ static void ParseAcceptLanguages(const std::string& accept_languages,
+ std::set<int>* languages);
+
+ FRIEND_TEST_ALL_PREFIXES(LanguageUsageMetricsTest, ParseAcceptLanguages);
+};
+
+} // namespace language_usage_metrics
+
+#endif // COMPONENTS_LANGUAGE_USAGE_METRICS_LANGUAGE_USAGE_METRICS_H_
diff --git a/components/language_usage_metrics/language_usage_metrics_unittest.cc b/components/language_usage_metrics/language_usage_metrics_unittest.cc
new file mode 100644
index 0000000..74344eb
--- /dev/null
+++ b/components/language_usage_metrics/language_usage_metrics_unittest.cc
@@ -0,0 +1,107 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/language_usage_metrics/language_usage_metrics.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace language_usage_metrics {
+
+TEST(LanguageUsageMetricsTest, ParseAcceptLanguages) {
+ std::set<int> language_set;
+ std::set<int>::const_iterator it;
+
+ const int ENGLISH = 25966;
+ const int SPANISH = 25971;
+ const int JAPANESE = 27233;
+
+ // Basic single language case.
+ LanguageUsageMetrics::ParseAcceptLanguages("ja", &language_set);
+ EXPECT_EQ(1U, language_set.size());
+ EXPECT_EQ(JAPANESE, *language_set.begin());
+
+ // Empty language.
+ LanguageUsageMetrics::ParseAcceptLanguages(std::string(), &language_set);
+ EXPECT_EQ(0U, language_set.size());
+
+ // Country code is ignored.
+ LanguageUsageMetrics::ParseAcceptLanguages("ja-JP", &language_set);
+ EXPECT_EQ(1U, language_set.size());
+ EXPECT_EQ(JAPANESE, *language_set.begin());
+
+ // Case is ignored.
+ LanguageUsageMetrics::ParseAcceptLanguages("Ja-jP", &language_set);
+ EXPECT_EQ(1U, language_set.size());
+ EXPECT_EQ(JAPANESE, *language_set.begin());
+
+ // Underscore as the separator.
+ LanguageUsageMetrics::ParseAcceptLanguages("ja_JP", &language_set);
+ EXPECT_EQ(1U, language_set.size());
+ EXPECT_EQ(JAPANESE, *language_set.begin());
+
+ // The result contains a same language code only once.
+ LanguageUsageMetrics::ParseAcceptLanguages("ja-JP,ja", &language_set);
+ EXPECT_EQ(1U, language_set.size());
+ EXPECT_EQ(JAPANESE, *language_set.begin());
+
+ // Basic two languages case.
+ LanguageUsageMetrics::ParseAcceptLanguages("en,ja", &language_set);
+ EXPECT_EQ(2U, language_set.size());
+ it = language_set.begin();
+ EXPECT_EQ(ENGLISH, *it);
+ EXPECT_EQ(JAPANESE, *++it);
+
+ // Multiple languages.
+ LanguageUsageMetrics::ParseAcceptLanguages("ja-JP,en,es,ja,en-US",
+ &language_set);
+ EXPECT_EQ(3U, language_set.size());
+ it = language_set.begin();
+ EXPECT_EQ(ENGLISH, *it);
+ EXPECT_EQ(SPANISH, *++it);
+ EXPECT_EQ(JAPANESE, *++it);
+
+ // Two empty languages.
+ LanguageUsageMetrics::ParseAcceptLanguages(",", &language_set);
+ EXPECT_EQ(0U, language_set.size());
+
+ // Trailing comma.
+ LanguageUsageMetrics::ParseAcceptLanguages("ja,", &language_set);
+ EXPECT_EQ(1U, language_set.size());
+ EXPECT_EQ(JAPANESE, *language_set.begin());
+
+ // Leading comma.
+ LanguageUsageMetrics::ParseAcceptLanguages(",es", &language_set);
+ EXPECT_EQ(1U, language_set.size());
+ EXPECT_EQ(SPANISH, *language_set.begin());
+
+ // Combination of invalid and valid.
+ LanguageUsageMetrics::ParseAcceptLanguages("1234,en", &language_set);
+ EXPECT_EQ(1U, language_set.size());
+ it = language_set.begin();
+ EXPECT_EQ(ENGLISH, *it);
+}
+
+TEST(LanguageUsageMetricsTest, ToLanguageCode) {
+ const int SPANISH = 25971;
+ const int JAPANESE = 27233;
+
+ // Basic case.
+ EXPECT_EQ(JAPANESE, LanguageUsageMetrics::ToLanguageCode("ja"));
+
+ // Case is ignored.
+ EXPECT_EQ(SPANISH, LanguageUsageMetrics::ToLanguageCode("Es"));
+
+ // Coutry code is ignored.
+ EXPECT_EQ(JAPANESE, LanguageUsageMetrics::ToLanguageCode("ja-JP"));
+
+ // Invalid locales are considered as unknown language.
+ EXPECT_EQ(0, LanguageUsageMetrics::ToLanguageCode(std::string()));
+ EXPECT_EQ(0, LanguageUsageMetrics::ToLanguageCode("1234"));
+
+ // "xx" is not acceptable because it doesn't exist in ISO 639-1 table.
+ // However, LanguageUsageMetrics doesn't tell what code is valid.
+ EXPECT_EQ(30840, LanguageUsageMetrics::ToLanguageCode("xx"));
+}
+
+} // namespace language_usage_metrics
diff --git a/components/translate.gypi b/components/translate.gypi
index 7c63eb9..474b529 100644
--- a/components/translate.gypi
+++ b/components/translate.gypi
@@ -8,6 +8,7 @@
'target_name': 'translate_core_browser',
'type': 'static_library',
'dependencies': [
+ 'language_usage_metrics',
'translate_core_common',
'../base/base.gyp:base',
'../url/url.gyp:url_lib',
@@ -17,6 +18,8 @@
],
'sources': [
'translate/core/browser/page_translated_details.h',
+ 'translate/core/browser/translate_browser_metrics.cc',
+ 'translate/core/browser/translate_browser_metrics.h',
'translate/core/browser/translate_error_details.h',
'translate/core/browser/translate_event_details.cc',
'translate/core/browser/translate_event_details.h',
diff --git a/components/translate/DEPS b/components/translate/DEPS
index 8f4bfc0..c2106de 100644
--- a/components/translate/DEPS
+++ b/components/translate/DEPS
@@ -1,4 +1,8 @@
include_rules = [
- # translate is used on iOS, which cannot depend on content.
+ "+components/language_usage_metrics",
+
+ # Translate is a layered component; subdirectories must explicitly introduce
+ # the ability to use the content layer as appropriate.
"-content",
+ "-components/translate/content",
]
diff --git a/components/translate/core/browser/translate_browser_metrics.cc b/components/translate/core/browser/translate_browser_metrics.cc
new file mode 100644
index 0000000..c0d3357d
--- /dev/null
+++ b/components/translate/core/browser/translate_browser_metrics.cc
@@ -0,0 +1,94 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/translate/core/browser/translate_browser_metrics.h"
+
+#include <string>
+
+#include "base/basictypes.h"
+#include "base/metrics/histogram.h"
+#include "base/metrics/sparse_histogram.h"
+#include "components/language_usage_metrics/language_usage_metrics.h"
+
+namespace {
+
+// Constant string values to indicate UMA names. All entries should have
+// a corresponding index in MetricsNameIndex and an entry in |kMetricsEntries|.
+const char kTranslateInitiationStatus[] =
+ "Translate.InitiationStatus.v2";
+const char kTranslateReportLanguageDetectionError[] =
+ "Translate.ReportLanguageDetectionError";
+const char kTranslateLocalesOnDisabledByPrefs[] =
+ "Translate.LocalesOnDisabledByPrefs";
+const char kTranslateUndisplayableLanguage[] =
+ "Translate.UndisplayableLanguage";
+const char kTranslateUnsupportedLanguageAtInitiation[] =
+ "Translate.UnsupportedLanguageAtInitiation";
+
+struct MetricsEntry {
+ TranslateBrowserMetrics::MetricsNameIndex index;
+ const char* const name;
+};
+
+// This entry table should be updated when new UMA items are added.
+const MetricsEntry kMetricsEntries[] = {
+ { TranslateBrowserMetrics::UMA_INITIATION_STATUS,
+ kTranslateInitiationStatus },
+ { TranslateBrowserMetrics::UMA_LANGUAGE_DETECTION_ERROR,
+ kTranslateReportLanguageDetectionError },
+ { TranslateBrowserMetrics::UMA_LOCALES_ON_DISABLED_BY_PREFS,
+ kTranslateLocalesOnDisabledByPrefs },
+ { TranslateBrowserMetrics::UMA_UNDISPLAYABLE_LANGUAGE,
+ kTranslateUndisplayableLanguage },
+ { TranslateBrowserMetrics::UMA_UNSUPPORTED_LANGUAGE_AT_INITIATION,
+ kTranslateUnsupportedLanguageAtInitiation },
+};
+
+COMPILE_ASSERT(arraysize(kMetricsEntries) == TranslateBrowserMetrics::UMA_MAX,
+ arraysize_of_kMetricsEntries_should_be_UMA_MAX);
+
+} // namespace
+
+namespace TranslateBrowserMetrics {
+
+void ReportInitiationStatus(InitiationStatusType type) {
+ UMA_HISTOGRAM_ENUMERATION(kTranslateInitiationStatus,
+ type,
+ INITIATION_STATUS_MAX);
+}
+
+void ReportLanguageDetectionError() {
+ UMA_HISTOGRAM_BOOLEAN(kTranslateReportLanguageDetectionError, true);
+}
+
+void ReportLocalesOnDisabledByPrefs(const std::string& locale) {
+ UMA_HISTOGRAM_SPARSE_SLOWLY(
+ kTranslateLocalesOnDisabledByPrefs,
+ language_usage_metrics::LanguageUsageMetrics::ToLanguageCode(locale));
+}
+
+void ReportUndisplayableLanguage(const std::string& language) {
+ int language_code =
+ language_usage_metrics::LanguageUsageMetrics::ToLanguageCode(language);
+ UMA_HISTOGRAM_SPARSE_SLOWLY(kTranslateUndisplayableLanguage,
+ language_code);
+}
+
+void ReportUnsupportedLanguageAtInitiation(const std::string& language) {
+ int language_code =
+ language_usage_metrics::LanguageUsageMetrics::ToLanguageCode(language);
+ UMA_HISTOGRAM_SPARSE_SLOWLY(kTranslateUnsupportedLanguageAtInitiation,
+ language_code);
+}
+
+const char* GetMetricsName(MetricsNameIndex index) {
+ for (size_t i = 0; i < arraysize(kMetricsEntries); ++i) {
+ if (kMetricsEntries[i].index == index)
+ return kMetricsEntries[i].name;
+ }
+ NOTREACHED();
+ return NULL;
+}
+
+} // namespace TranslateBrowserMetrics
diff --git a/components/translate/core/browser/translate_browser_metrics.h b/components/translate/core/browser/translate_browser_metrics.h
new file mode 100644
index 0000000..0d76e7b
--- /dev/null
+++ b/components/translate/core/browser/translate_browser_metrics.h
@@ -0,0 +1,64 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_TRANSLATE_CORE_BROWSER_TRANSLATE_BROWSER_METRICS_H_
+#define COMPONENTS_TRANSLATE_CORE_BROWSER_TRANSLATE_BROWSER_METRICS_H_
+
+#include <string>
+
+namespace TranslateBrowserMetrics {
+
+// An indexing type to query each UMA entry name via GetMetricsName() function.
+// Note: |kMetricsEntries| should be updated when a new entry is added here.
+enum MetricsNameIndex {
+ UMA_INITIATION_STATUS,
+ UMA_LANGUAGE_DETECTION_ERROR,
+ UMA_LOCALES_ON_DISABLED_BY_PREFS,
+ UMA_UNDISPLAYABLE_LANGUAGE,
+ UMA_UNSUPPORTED_LANGUAGE_AT_INITIATION,
+ UMA_MAX,
+};
+
+// When Chrome Translate is ready to translate a page, one of following reason
+// decide the next browser action.
+// Note: Don't insert any item. It will change reporting UMA value, and break
+// the UMA dashboard page. Insteads, append it at the end of enum as suggested
+// below.
+enum InitiationStatusType {
+ INITIATION_STATUS_DISABLED_BY_PREFS,
+ INITIATION_STATUS_DISABLED_BY_SWITCH,
+ INITIATION_STATUS_DISABLED_BY_CONFIG,
+ INITIATION_STATUS_LANGUAGE_IS_NOT_SUPPORTED,
+ INITIATION_STATUS_URL_IS_NOT_SUPPORTED,
+ INITIATION_STATUS_SIMILAR_LANGUAGES,
+ INITIATION_STATUS_ACCEPT_LANGUAGES,
+ INITIATION_STATUS_AUTO_BY_CONFIG,
+ INITIATION_STATUS_AUTO_BY_LINK,
+ INITIATION_STATUS_SHOW_INFOBAR,
+ INITIATION_STATUS_MIME_TYPE_IS_NOT_SUPPORTED,
+ // Insert new items here.
+ INITIATION_STATUS_MAX,
+};
+
+// Called when Chrome Translate is initiated to report a reason of the next
+// browser action.
+void ReportInitiationStatus(InitiationStatusType type);
+
+// Called when Chrome opens the URL so that the user sends an error feedback.
+void ReportLanguageDetectionError();
+
+void ReportLocalesOnDisabledByPrefs(const std::string& locale);
+
+// Called when Chrome Translate server sends the language list which includes
+// a undisplayable language in the user's locale.
+void ReportUndisplayableLanguage(const std::string& language);
+
+void ReportUnsupportedLanguageAtInitiation(const std::string& language);
+
+// Provides UMA entry names for unit tests.
+const char* GetMetricsName(MetricsNameIndex index);
+
+} // namespace TranslateBrowserMetrics
+
+#endif // COMPONENTS_TRANSLATE_CORE_BROWSER_TRANSLATE_BROWSER_METRICS_H_
diff --git a/components/translate/core/browser/translate_browser_metrics_unittest.cc b/components/translate/core/browser/translate_browser_metrics_unittest.cc
new file mode 100644
index 0000000..404014f
--- /dev/null
+++ b/components/translate/core/browser/translate_browser_metrics_unittest.cc
@@ -0,0 +1,187 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/translate/core/browser/translate_browser_metrics.h"
+
+#include "base/basictypes.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/metrics/histogram.h"
+#include "base/metrics/histogram_samples.h"
+#include "base/metrics/statistics_recorder.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "testing/platform_test.h"
+
+using base::HistogramBase;
+using base::HistogramSamples;
+using base::StatisticsRecorder;
+
+namespace {
+
+class MetricsRecorder {
+ public:
+ explicit MetricsRecorder(const char* key) : key_(key) {
+ StatisticsRecorder::Initialize();
+
+ HistogramBase* histogram = StatisticsRecorder::FindHistogram(key_);
+ if (histogram)
+ base_samples_ = histogram->SnapshotSamples();
+ }
+
+ void CheckInitiationStatus(int expected_disabled_by_prefs,
+ int expected_disabled_by_switch,
+ int expected_disabled_by_config,
+ int expected_language_is_not_supported,
+ int expected_mime_type_is_not_supported,
+ int expected_url_is_not_supported,
+ int expected_similar_languages,
+ int expected_accept_languages,
+ int expected_auto_by_config,
+ int expected_auto_by_link,
+ int expected_show_infobar) {
+ Snapshot();
+
+ EXPECT_EQ(expected_disabled_by_prefs, GetCountWithoutSnapshot(
+ TranslateBrowserMetrics::INITIATION_STATUS_DISABLED_BY_PREFS));
+ EXPECT_EQ(expected_disabled_by_switch, GetCountWithoutSnapshot(
+ TranslateBrowserMetrics::INITIATION_STATUS_DISABLED_BY_SWITCH));
+ EXPECT_EQ(expected_disabled_by_config, GetCountWithoutSnapshot(
+ TranslateBrowserMetrics::INITIATION_STATUS_DISABLED_BY_CONFIG));
+ EXPECT_EQ(expected_language_is_not_supported, GetCountWithoutSnapshot(
+ TranslateBrowserMetrics::INITIATION_STATUS_LANGUAGE_IS_NOT_SUPPORTED));
+ EXPECT_EQ(expected_mime_type_is_not_supported, GetCountWithoutSnapshot(
+ TranslateBrowserMetrics::INITIATION_STATUS_MIME_TYPE_IS_NOT_SUPPORTED));
+ EXPECT_EQ(expected_url_is_not_supported, GetCountWithoutSnapshot(
+ TranslateBrowserMetrics::INITIATION_STATUS_URL_IS_NOT_SUPPORTED));
+ EXPECT_EQ(expected_similar_languages, GetCountWithoutSnapshot(
+ TranslateBrowserMetrics::INITIATION_STATUS_SIMILAR_LANGUAGES));
+ EXPECT_EQ(expected_accept_languages, GetCountWithoutSnapshot(
+ TranslateBrowserMetrics::INITIATION_STATUS_ACCEPT_LANGUAGES));
+ EXPECT_EQ(expected_auto_by_config, GetCountWithoutSnapshot(
+ TranslateBrowserMetrics::INITIATION_STATUS_AUTO_BY_CONFIG));
+ EXPECT_EQ(expected_auto_by_link, GetCountWithoutSnapshot(
+ TranslateBrowserMetrics::INITIATION_STATUS_AUTO_BY_LINK));
+ EXPECT_EQ(expected_show_infobar, GetCountWithoutSnapshot(
+ TranslateBrowserMetrics::INITIATION_STATUS_SHOW_INFOBAR));
+ }
+
+ HistogramBase::Count GetTotalCount() {
+ Snapshot();
+ if (!samples_.get())
+ return 0;
+ HistogramBase::Count count = samples_->TotalCount();
+ if (!base_samples_.get())
+ return count;
+ return count - base_samples_->TotalCount();
+ }
+
+ HistogramBase::Count GetCount(HistogramBase::Sample value) {
+ Snapshot();
+ return GetCountWithoutSnapshot(value);
+ }
+
+ private:
+ void Snapshot() {
+ HistogramBase* histogram = StatisticsRecorder::FindHistogram(key_);
+ if (!histogram)
+ return;
+ samples_ = histogram->SnapshotSamples();
+ }
+
+ HistogramBase::Count GetCountWithoutSnapshot(HistogramBase::Sample value) {
+ if (!samples_.get())
+ return 0;
+ HistogramBase::Count count = samples_->GetCount(value);
+ if (!base_samples_.get())
+ return count;
+ return count - base_samples_->GetCount(value);
+ }
+
+ std::string key_;
+ scoped_ptr<HistogramSamples> base_samples_;
+ scoped_ptr<HistogramSamples> samples_;
+
+ DISALLOW_COPY_AND_ASSIGN(MetricsRecorder);
+};
+
+} // namespace
+
+TEST(TranslateBrowserMetricsTest, ReportInitiationStatus) {
+ MetricsRecorder recorder(TranslateBrowserMetrics::GetMetricsName(
+ TranslateBrowserMetrics::UMA_INITIATION_STATUS));
+
+ recorder.CheckInitiationStatus(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+ TranslateBrowserMetrics::ReportInitiationStatus(
+ TranslateBrowserMetrics::INITIATION_STATUS_DISABLED_BY_PREFS);
+ recorder.CheckInitiationStatus(1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+ TranslateBrowserMetrics::ReportInitiationStatus(
+ TranslateBrowserMetrics::INITIATION_STATUS_DISABLED_BY_SWITCH);
+ recorder.CheckInitiationStatus(1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+ TranslateBrowserMetrics::ReportInitiationStatus(
+ TranslateBrowserMetrics::INITIATION_STATUS_DISABLED_BY_CONFIG);
+ recorder.CheckInitiationStatus(1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0);
+ TranslateBrowserMetrics::ReportInitiationStatus(
+ TranslateBrowserMetrics::INITIATION_STATUS_LANGUAGE_IS_NOT_SUPPORTED);
+ recorder.CheckInitiationStatus(1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0);
+ TranslateBrowserMetrics::ReportInitiationStatus(
+ TranslateBrowserMetrics::INITIATION_STATUS_MIME_TYPE_IS_NOT_SUPPORTED);
+ recorder.CheckInitiationStatus(1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0);
+ TranslateBrowserMetrics::ReportInitiationStatus(
+ TranslateBrowserMetrics::INITIATION_STATUS_URL_IS_NOT_SUPPORTED);
+ recorder.CheckInitiationStatus(1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0);
+ TranslateBrowserMetrics::ReportInitiationStatus(
+ TranslateBrowserMetrics::INITIATION_STATUS_SIMILAR_LANGUAGES);
+ recorder.CheckInitiationStatus(1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0);
+ TranslateBrowserMetrics::ReportInitiationStatus(
+ TranslateBrowserMetrics::INITIATION_STATUS_ACCEPT_LANGUAGES);
+ recorder.CheckInitiationStatus(1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0);
+ TranslateBrowserMetrics::ReportInitiationStatus(
+ TranslateBrowserMetrics::INITIATION_STATUS_AUTO_BY_CONFIG);
+ recorder.CheckInitiationStatus(1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0);
+ TranslateBrowserMetrics::ReportInitiationStatus(
+ TranslateBrowserMetrics::INITIATION_STATUS_AUTO_BY_LINK);
+ recorder.CheckInitiationStatus(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0);
+ TranslateBrowserMetrics::ReportInitiationStatus(
+ TranslateBrowserMetrics::INITIATION_STATUS_SHOW_INFOBAR);
+ recorder.CheckInitiationStatus(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1);
+}
+
+TEST(TranslateBrowserMetricsTest, ReportLanguageDetectionError) {
+ MetricsRecorder recorder(TranslateBrowserMetrics::GetMetricsName(
+ TranslateBrowserMetrics::UMA_LANGUAGE_DETECTION_ERROR));
+ EXPECT_EQ(0, recorder.GetTotalCount());
+ TranslateBrowserMetrics::ReportLanguageDetectionError();
+ EXPECT_EQ(1, recorder.GetTotalCount());
+
+}
+
+
+TEST(TranslateBrowserMetricsTest, ReportedLocalesOnDisabledByPrefs) {
+ const int ENGLISH = 25966;
+
+ MetricsRecorder recorder(TranslateBrowserMetrics::GetMetricsName(
+ TranslateBrowserMetrics::UMA_LOCALES_ON_DISABLED_BY_PREFS));
+ EXPECT_EQ(0, recorder.GetTotalCount());
+ TranslateBrowserMetrics::ReportLocalesOnDisabledByPrefs("en");
+ EXPECT_EQ(1, recorder.GetCount(ENGLISH));
+}
+
+TEST(TranslateBrowserMetricsTest, ReportedUndisplayableLanguage) {
+ const int ENGLISH = 25966;
+
+ MetricsRecorder recorder(TranslateBrowserMetrics::GetMetricsName(
+ TranslateBrowserMetrics::UMA_UNDISPLAYABLE_LANGUAGE));
+ EXPECT_EQ(0, recorder.GetTotalCount());
+ TranslateBrowserMetrics::ReportUndisplayableLanguage("en");
+ EXPECT_EQ(1, recorder.GetCount(ENGLISH));
+}
+
+TEST(TranslateBrowserMetricsTest, ReportedUnsupportedLanguageAtInitiation) {
+ const int ENGLISH = 25966;
+
+ MetricsRecorder recorder(TranslateBrowserMetrics::GetMetricsName(
+ TranslateBrowserMetrics::UMA_UNSUPPORTED_LANGUAGE_AT_INITIATION));
+ EXPECT_EQ(0, recorder.GetTotalCount());
+ TranslateBrowserMetrics::ReportUnsupportedLanguageAtInitiation("en");
+ EXPECT_EQ(1, recorder.GetCount(ENGLISH));
+}