summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--base/base.gyp1
-rw-r--r--base/metrics/histogram.h18
-rw-r--r--base/metrics/histogram_base.h19
-rw-r--r--base/metrics/histogram_delta_serialization.cc2
-rw-r--r--base/metrics/histogram_snapshot_manager.cc11
-rw-r--r--base/metrics/histogram_snapshot_manager.h10
-rw-r--r--base/metrics/histogram_snapshot_manager_unittest.cc106
-rw-r--r--base/metrics/statistics_recorder.h1
-rw-r--r--chrome/android/java/ActivityTypeIds.template11
-rw-r--r--chrome/browser/android/activity_type_id_list.h19
-rw-r--r--chrome/browser/android/activity_type_ids.cc19
-rw-r--r--chrome/browser/android/activity_type_ids.h23
-rw-r--r--chrome/browser/metrics/metrics_service.cc19
-rw-r--r--chrome/browser/metrics/metrics_service.h22
-rw-r--r--chrome/browser/metrics/metrics_service_android.cc143
-rw-r--r--chrome/chrome.gyp1
-rw-r--r--chrome/chrome_browser.gypi16
-rw-r--r--chrome/common/metrics/metrics_service_base.cc9
-rw-r--r--chrome/common/metrics/metrics_service_base.h4
-rw-r--r--chrome/common/pref_names.cc23
-rw-r--r--chrome/common/pref_names.h6
-rw-r--r--tools/metrics/histograms/histograms.xml24
22 files changed, 486 insertions, 21 deletions
diff --git a/base/base.gyp b/base/base.gyp
index 4269485..78e6ddb 100644
--- a/base/base.gyp
+++ b/base/base.gyp
@@ -554,6 +554,7 @@
'metrics/field_trial_unittest.cc',
'metrics/histogram_base_unittest.cc',
'metrics/histogram_delta_serialization_unittest.cc',
+ 'metrics/histogram_snapshot_manager_unittest.cc',
'metrics/histogram_unittest.cc',
'metrics/sparse_histogram_unittest.cc',
'metrics/stats_table_unittest.cc',
diff --git a/base/metrics/histogram.h b/base/metrics/histogram.h
index 9845362..7a6c688 100644
--- a/base/metrics/histogram.h
+++ b/base/metrics/histogram.h
@@ -190,6 +190,12 @@ class Lock;
base::Histogram::FactoryGet(name, min, max, bucket_count, \
base::HistogramBase::kNoFlags))
+// This is a helper macro used by other macros and shouldn't be used directly.
+#define HISTOGRAM_ENUMERATION_WITH_FLAG(name, sample, boundary, flag) \
+ STATIC_HISTOGRAM_POINTER_BLOCK(name, Add(sample), \
+ base::LinearHistogram::FactoryGet(name, 1, boundary, boundary + 1, \
+ flag))
+
#define HISTOGRAM_PERCENTAGE(name, under_one_hundred) \
HISTOGRAM_ENUMERATION(name, under_one_hundred, 101)
@@ -349,9 +355,15 @@ class Lock;
// The samples should always be strictly less than |boundary_value|. For more
// details, see the comment for the |HISTOGRAM_ENUMERATION| macro, above.
#define UMA_HISTOGRAM_ENUMERATION(name, sample, boundary_value) \
- STATIC_HISTOGRAM_POINTER_BLOCK(name, Add(sample), \
- base::LinearHistogram::FactoryGet(name, 1, boundary_value, \
- boundary_value + 1, base::HistogramBase::kUmaTargetedHistogramFlag))
+ HISTOGRAM_ENUMERATION_WITH_FLAG(name, sample, boundary_value, \
+ base::HistogramBase::kUmaTargetedHistogramFlag)
+
+// Similar to UMA_HISTOGRAM_ENUMERATION, but used for recording stability
+// histograms. Use this if recording a histogram that should be part of the
+// initial stability log.
+#define UMA_STABILITY_HISTOGRAM_ENUMERATION(name, sample, boundary_value) \
+ HISTOGRAM_ENUMERATION_WITH_FLAG(name, sample, boundary_value, \
+ base::HistogramBase::kUmaStabilityHistogramFlag)
#define UMA_HISTOGRAM_CUSTOM_ENUMERATION(name, sample, custom_ranges) \
STATIC_HISTOGRAM_POINTER_BLOCK(name, Add(sample), \
diff --git a/base/metrics/histogram_base.h b/base/metrics/histogram_base.h
index 11b9a45b..f3e9b46 100644
--- a/base/metrics/histogram_base.h
+++ b/base/metrics/histogram_base.h
@@ -56,13 +56,20 @@ class BASE_EXPORT HistogramBase {
enum Flags {
kNoFlags = 0,
- kUmaTargetedHistogramFlag = 0x1, // Histogram should be UMA uploaded.
- // Indicate that the histogram was pickled to be sent across an IPC Channel.
- // If we observe this flag on a histogram being aggregated into after IPC,
- // then we are running in a single process mode, and the aggregation should
- // not take place (as we would be aggregating back into the source
- // histogram!).
+ // Histogram should be UMA uploaded.
+ kUmaTargetedHistogramFlag = 0x1,
+
+ // Indicates that this is a stability histogram. This flag exists to specify
+ // which histograms should be included in the initial stability log. Please
+ // refer to |MetricsService::PrepareInitialStabilityLog|.
+ kUmaStabilityHistogramFlag = kUmaTargetedHistogramFlag | 0x2,
+
+ // Indicates that the histogram was pickled to be sent across an IPC
+ // Channel. If we observe this flag on a histogram being aggregated into
+ // after IPC, then we are running in a single process mode, and the
+ // aggregation should not take place (as we would be aggregating back into
+ // the source histogram!).
kIPCSerializationSourceFlag = 0x10,
// Only for Histogram and its sub classes: fancy bucket-naming support.
diff --git a/base/metrics/histogram_delta_serialization.cc b/base/metrics/histogram_delta_serialization.cc
index e40a6b6..e4aad13 100644
--- a/base/metrics/histogram_delta_serialization.cc
+++ b/base/metrics/histogram_delta_serialization.cc
@@ -66,7 +66,7 @@ void HistogramDeltaSerialization::PrepareAndSerializeDeltas(
// the histograms, so that the receiving process can distinguish them from the
// local histograms.
histogram_snapshot_manager_.PrepareDeltas(
- Histogram::kIPCSerializationSourceFlag, false);
+ Histogram::kIPCSerializationSourceFlag, Histogram::kNoFlags);
serialized_deltas_ = NULL;
}
diff --git a/base/metrics/histogram_snapshot_manager.cc b/base/metrics/histogram_snapshot_manager.cc
index cb594bd..b1e26da 100644
--- a/base/metrics/histogram_snapshot_manager.cc
+++ b/base/metrics/histogram_snapshot_manager.cc
@@ -25,18 +25,17 @@ HistogramSnapshotManager::~HistogramSnapshotManager() {
STLDeleteValues(&logged_samples_);
}
-void HistogramSnapshotManager::PrepareDeltas(HistogramBase::Flags flag_to_set,
- bool record_only_uma) {
+void HistogramSnapshotManager::PrepareDeltas(
+ HistogramBase::Flags flag_to_set,
+ HistogramBase::Flags required_flags) {
StatisticsRecorder::Histograms histograms;
StatisticsRecorder::GetHistograms(&histograms);
for (StatisticsRecorder::Histograms::const_iterator it = histograms.begin();
histograms.end() != it;
++it) {
(*it)->SetFlags(flag_to_set);
- if (record_only_uma &&
- 0 == ((*it)->flags() & Histogram::kUmaTargetedHistogramFlag))
- continue;
- PrepareDelta(**it);
+ if (((*it)->flags() & required_flags) == required_flags)
+ PrepareDelta(**it);
}
}
diff --git a/base/metrics/histogram_snapshot_manager.h b/base/metrics/histogram_snapshot_manager.h
index 3c70508..5a5f2e9 100644
--- a/base/metrics/histogram_snapshot_manager.h
+++ b/base/metrics/histogram_snapshot_manager.h
@@ -29,9 +29,13 @@ class BASE_EXPORT HistogramSnapshotManager {
virtual ~HistogramSnapshotManager();
// Snapshot all histograms, and ask |histogram_flattener_| to record the
- // delta. The arguments allow selecting only a subset of histograms for
- // recording, or to set a flag in each recorded histogram.
- void PrepareDeltas(HistogramBase::Flags flags_to_set, bool record_only_uma);
+ // delta. |flags_to_set| is used to set flags for each histogram.
+ // |required_flags| is used to select histograms to be recorded.
+ // Only histograms that have all the flags specified by the argument will be
+ // chosen. If all histograms should be recorded, set it to
+ // |Histogram::kNoFlags|.
+ void PrepareDeltas(HistogramBase::Flags flags_to_set,
+ HistogramBase::Flags required_flags);
private:
// Snapshot this histogram, and record the delta.
diff --git a/base/metrics/histogram_snapshot_manager_unittest.cc b/base/metrics/histogram_snapshot_manager_unittest.cc
new file mode 100644
index 0000000..e6672ea
--- /dev/null
+++ b/base/metrics/histogram_snapshot_manager_unittest.cc
@@ -0,0 +1,106 @@
+// 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 "base/metrics/histogram_snapshot_manager.h"
+
+#include <string>
+#include <vector>
+
+#include "base/metrics/histogram.h"
+#include "base/metrics/histogram_delta_serialization.h"
+#include "base/metrics/statistics_recorder.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace base {
+
+class HistogramFlattenerDeltaRecorder : public HistogramFlattener {
+ public:
+ HistogramFlattenerDeltaRecorder() {}
+
+ virtual void RecordDelta(const HistogramBase& histogram,
+ const HistogramSamples& snapshot) OVERRIDE {
+ recorded_delta_histogram_names_.push_back(histogram.histogram_name());
+ }
+
+ virtual void InconsistencyDetected(
+ HistogramBase::Inconsistency problem) OVERRIDE {
+ ASSERT_TRUE(false);
+ }
+
+ virtual void UniqueInconsistencyDetected(
+ HistogramBase::Inconsistency problem) OVERRIDE {
+ ASSERT_TRUE(false);
+ }
+
+ virtual void InconsistencyDetectedInLoggedCount(int amount) OVERRIDE {
+ ASSERT_TRUE(false);
+ }
+
+ std::vector<std::string> GetRecordedDeltaHistogramNames() {
+ return recorded_delta_histogram_names_;
+ }
+
+ private:
+ std::vector<std::string> recorded_delta_histogram_names_;
+
+ DISALLOW_COPY_AND_ASSIGN(HistogramFlattenerDeltaRecorder);
+};
+
+class HistogramSnapshotManagerTest : public testing::Test {
+ protected:
+ HistogramSnapshotManagerTest()
+ : histogram_snapshot_manager_(&histogram_flattener_delta_recorder_) {}
+
+ virtual ~HistogramSnapshotManagerTest() {}
+
+ StatisticsRecorder statistics_recorder_;
+ HistogramFlattenerDeltaRecorder histogram_flattener_delta_recorder_;
+ HistogramSnapshotManager histogram_snapshot_manager_;
+};
+
+TEST_F(HistogramSnapshotManagerTest, PrepareDeltasNoFlagsFilter) {
+ // kNoFlags filter should record all histograms.
+ UMA_HISTOGRAM_ENUMERATION("UmaHistogram", 1, 2);
+ UMA_STABILITY_HISTOGRAM_ENUMERATION("UmaStabilityHistogram", 1, 2);
+
+ histogram_snapshot_manager_.PrepareDeltas(HistogramBase::kNoFlags,
+ HistogramBase::kNoFlags);
+
+ const std::vector<std::string>& histograms =
+ histogram_flattener_delta_recorder_.GetRecordedDeltaHistogramNames();
+ EXPECT_EQ(2U, histograms.size());
+ EXPECT_EQ("UmaHistogram", histograms[0]);
+ EXPECT_EQ("UmaStabilityHistogram", histograms[1]);
+}
+
+TEST_F(HistogramSnapshotManagerTest, PrepareDeltasUmaHistogramFlagFilter) {
+ // Note that kUmaStabilityHistogramFlag includes kUmaTargetedHistogramFlag.
+ UMA_HISTOGRAM_ENUMERATION("UmaHistogram", 1, 2);
+ UMA_STABILITY_HISTOGRAM_ENUMERATION("UmaStabilityHistogram", 1, 2);
+
+ histogram_snapshot_manager_.PrepareDeltas(
+ HistogramBase::kNoFlags, HistogramBase::kUmaTargetedHistogramFlag);
+
+ const std::vector<std::string>& histograms =
+ histogram_flattener_delta_recorder_.GetRecordedDeltaHistogramNames();
+ EXPECT_EQ(2U, histograms.size());
+ EXPECT_EQ("UmaHistogram", histograms[0]);
+ EXPECT_EQ("UmaStabilityHistogram", histograms[1]);
+}
+
+TEST_F(HistogramSnapshotManagerTest,
+ PrepareDeltasUmaStabilityHistogramFlagFilter) {
+ UMA_HISTOGRAM_ENUMERATION("UmaHistogram", 1, 2);
+ UMA_STABILITY_HISTOGRAM_ENUMERATION("UmaStabilityHistogram", 1, 2);
+
+ histogram_snapshot_manager_.PrepareDeltas(
+ HistogramBase::kNoFlags, HistogramBase::kUmaStabilityHistogramFlag);
+
+ const std::vector<std::string>& histograms =
+ histogram_flattener_delta_recorder_.GetRecordedDeltaHistogramNames();
+ EXPECT_EQ(1U, histograms.size());
+ EXPECT_EQ("UmaStabilityHistogram", histograms[0]);
+}
+
+} // namespace base
diff --git a/base/metrics/statistics_recorder.h b/base/metrics/statistics_recorder.h
index 5e53f274..7a81826 100644
--- a/base/metrics/statistics_recorder.h
+++ b/base/metrics/statistics_recorder.h
@@ -86,6 +86,7 @@ class BASE_EXPORT StatisticsRecorder {
friend struct DefaultLazyInstanceTraits<StatisticsRecorder>;
friend class HistogramBaseTest;
+ friend class HistogramSnapshotManagerTest;
friend class HistogramTest;
friend class SparseHistogramTest;
friend class StatisticsDeltaReaderTest;
diff --git a/chrome/android/java/ActivityTypeIds.template b/chrome/android/java/ActivityTypeIds.template
new file mode 100644
index 0000000..4f64e8b
--- /dev/null
+++ b/chrome/android/java/ActivityTypeIds.template
@@ -0,0 +1,11 @@
+// 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.
+
+package org.chromium.chrome.browser;
+
+public class ActivityTypeIds {
+#define DEFINE_ACTIVITY_ID(id,value) public static final int ACTIVITY_##id = value;
+#include "chrome/browser/android/activity_type_id_list.h"
+#undef DEFINE_ACTIVITY_ID
+}
diff --git a/chrome/browser/android/activity_type_id_list.h b/chrome/browser/android/activity_type_id_list.h
new file mode 100644
index 0000000..805e15e
--- /dev/null
+++ b/chrome/browser/android/activity_type_id_list.h
@@ -0,0 +1,19 @@
+// 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.
+
+// Intentionally no include guards because this file is meant to be included
+// inside a macro to generate enum values.
+
+// Define Activities we are interested in tracking. IDs are assigned
+// consecutively, from NONE to MAX_VALUE. Activities that are not explicitly
+// defined are all assigned the UNKNOWN value. When adding new ones, make sure
+// to append them after current Activities and to update the |AndroidActivityId|
+// enum in |histograms.xml|.
+DEFINE_ACTIVITY_ID(NONE, 0)
+DEFINE_ACTIVITY_ID(UNKNOWN, 1)
+DEFINE_ACTIVITY_ID(MAIN, 2)
+DEFINE_ACTIVITY_ID(PREFERENCES, 3)
+DEFINE_ACTIVITY_ID(WEBAPPACTIVITY, 4)
+DEFINE_ACTIVITY_ID(FULLSCREENACTIVITY, 5)
+DEFINE_ACTIVITY_ID(MAX_VALUE, 6)
diff --git a/chrome/browser/android/activity_type_ids.cc b/chrome/browser/android/activity_type_ids.cc
new file mode 100644
index 0000000..98a1724
--- /dev/null
+++ b/chrome/browser/android/activity_type_ids.cc
@@ -0,0 +1,19 @@
+// 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 "chrome/browser/android/activity_type_ids.h"
+
+#include "base/logging.h"
+
+namespace ActivityTypeIds {
+
+Type GetActivityType(int type_id) {
+ if (type_id >= ACTIVITY_NONE && type_id <= ACTIVITY_MAX_VALUE)
+ return Type(type_id);
+
+ NOTREACHED() << "Unhandled Activity id was passed in: " << type_id;
+ return ACTIVITY_MAX_VALUE;
+}
+
+} // namespace ActivityTypeIds
diff --git a/chrome/browser/android/activity_type_ids.h b/chrome/browser/android/activity_type_ids.h
new file mode 100644
index 0000000..606f875
--- /dev/null
+++ b/chrome/browser/android/activity_type_ids.h
@@ -0,0 +1,23 @@
+// 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 CHROME_BROWSER_ANDROID_ACTIVITY_TYPE_IDS_H_
+#define CHROME_BROWSER_ANDROID_ACTIVITY_TYPE_IDS_H_
+
+// This file maps Activities on Chrome to specific flags for identification.
+
+namespace ActivityTypeIds {
+
+enum Type {
+#define DEFINE_ACTIVITY_ID(id,value) ACTIVITY_##id = (value),
+#include "activity_type_id_list.h"
+#undef DEFINE_ACTIVITY_ID
+}; // enum Type
+
+// Takes an int corresponding to a Type and returns the corresponding Type.
+Type GetActivityType(int type_id);
+
+} // namespace ActivityTypeIds
+
+#endif // CHROME_BROWSER_ANDROID_ACTIVITY_TYPE_IDS_H_
diff --git a/chrome/browser/metrics/metrics_service.cc b/chrome/browser/metrics/metrics_service.cc
index cc90ada..a3c0b83 100644
--- a/chrome/browser/metrics/metrics_service.cc
+++ b/chrome/browser/metrics/metrics_service.cc
@@ -482,6 +482,10 @@ void MetricsService::RegisterPrefs(PrefRegistrySimple* registry) {
registry->RegisterInt64Pref(prefs::kUninstallMetricsUptimeSec, 0);
registry->RegisterInt64Pref(prefs::kUninstallLastLaunchTimeSec, 0);
registry->RegisterInt64Pref(prefs::kUninstallLastObservedRunTimeSec, 0);
+
+#if defined(OS_ANDROID)
+ RegisterPrefsAndroid(registry);
+#endif // defined(OS_ANDROID)
}
// static
@@ -510,6 +514,10 @@ void MetricsService::DiscardOldStabilityStats(PrefService* local_state) {
local_state->ClearPref(prefs::kMetricsInitialLogs);
local_state->ClearPref(prefs::kMetricsOngoingLogs);
+
+#if defined(OS_ANDROID)
+ DiscardOldStabilityStatsAndroid(local_state);
+#endif // defined(OS_ANDROID)
}
MetricsService::MetricsService()
@@ -946,6 +954,10 @@ void MetricsService::InitializeMetricsState(ReportingState reporting_state) {
session_id_ = pref->GetInteger(prefs::kMetricsSessionID);
+#if defined(OS_ANDROID)
+ LogAndroidStabilityToPrefs(pref);
+#endif // defined(OS_ANDROID)
+
if (!pref->GetBoolean(prefs::kStabilityExitedCleanly)) {
IncrementPrefValue(prefs::kStabilityCrashCount);
// Reset flag, and wait until we call LogNeedForCleanShutdown() before
@@ -1534,6 +1546,10 @@ void MetricsService::PrepareInitialStabilityLog() {
log_manager_.PauseCurrentLog();
log_manager_.BeginLoggingWithLog(initial_stability_log.release(),
MetricsLog::INITIAL_LOG);
+#if defined(OS_ANDROID)
+ ConvertAndroidStabilityPrefsToHistograms(pref);
+ RecordCurrentStabilityHistograms();
+#endif // defined(OS_ANDROID)
log_manager_.FinishCurrentLog();
log_manager_.ResumePausedLog();
@@ -1560,6 +1576,9 @@ void MetricsService::PrepareInitialMetricsLog(MetricsLog::LogType log_type) {
// before writing them.
log_manager_.PauseCurrentLog();
log_manager_.BeginLoggingWithLog(initial_metrics_log_.release(), log_type);
+#if defined(OS_ANDROID)
+ ConvertAndroidStabilityPrefsToHistograms(pref);
+#endif // defined(OS_ANDROID)
RecordCurrentHistograms();
log_manager_.FinishCurrentLog();
log_manager_.ResumePausedLog();
diff --git a/chrome/browser/metrics/metrics_service.h b/chrome/browser/metrics/metrics_service.h
index dadbf59..199d6b7 100644
--- a/chrome/browser/metrics/metrics_service.h
+++ b/chrome/browser/metrics/metrics_service.h
@@ -30,7 +30,9 @@
#include "content/public/browser/user_metrics.h"
#include "net/url_request/url_fetcher_delegate.h"
-#if defined(OS_CHROMEOS)
+#if defined(OS_ANDROID)
+#include "chrome/browser/android/activity_type_ids.h"
+#elif defined(OS_CHROMEOS)
#include "chrome/browser/chromeos/external_metrics.h"
#endif
@@ -175,6 +177,9 @@ class MetricsService
// At startup, prefs needs to be called with a list of all the pref names and
// types we'll be using.
static void RegisterPrefs(PrefRegistrySimple* registry);
+#if defined(OS_ANDROID)
+ static void RegisterPrefsAndroid(PrefRegistrySimple* registry);
+#endif // defined(OS_ANDROID)
// Set up notifications which indicate that a user is performing work. This is
// useful to allow some features to sleep, until the machine becomes active,
@@ -203,6 +208,18 @@ class MetricsService
// that session end was successful.
void RecordCompletedSessionEnd();
+#if defined(OS_ANDROID)
+ // Called to log launch and crash stats to preferences.
+ void LogAndroidStabilityToPrefs(PrefService* pref);
+
+ // Converts crash stats stored in the preferences into histograms.
+ void ConvertAndroidStabilityPrefsToHistograms(PrefService* pref);
+
+ // Called when the Activity that the user interacts with is swapped out.
+ void OnForegroundActivityChanged(PrefService* pref,
+ ActivityTypeIds::Type type);
+#endif // defined(OS_ANDROID)
+
#if defined(OS_ANDROID) || defined(OS_IOS)
// Called when the application is going into background mode.
void OnAppEnterBackground();
@@ -346,6 +363,9 @@ class MetricsService
// the old version (after an autoupdate has arrived), and so we'd bias
// initial results towards showing crashes :-(.
static void DiscardOldStabilityStats(PrefService* local_state);
+#if defined(OS_ANDROID)
+ static void DiscardOldStabilityStatsAndroid(PrefService* local_state);
+#endif // defined(OS_ANDROID)
// Turns recording on or off.
// DisableRecording() also forces a persistent save of logging state (if
diff --git a/chrome/browser/metrics/metrics_service_android.cc b/chrome/browser/metrics/metrics_service_android.cc
new file mode 100644
index 0000000..30ee40e
--- /dev/null
+++ b/chrome/browser/metrics/metrics_service_android.cc
@@ -0,0 +1,143 @@
+// 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 "chrome/browser/metrics/metrics_service.h"
+
+#include "base/metrics/histogram.h"
+#include "base/prefs/pref_registry_simple.h"
+#include "base/prefs/pref_service.h"
+#include "base/prefs/scoped_user_pref_update.h"
+#include "base/values.h"
+#include "chrome/browser/android/activity_type_ids.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/common/pref_names.h"
+
+namespace {
+
+// Increments a particular entry in the ListValue.
+void IncrementListValue(base::ListValue* counts, int index) {
+ int current_count = 0;
+ counts->GetInteger(index, &current_count);
+ counts->Set(index, new base::FundamentalValue(current_count + 1));
+}
+
+// Takes an int corresponding to a Type and returns the corresponding flag.
+int GetActivityFlag(int type_id) {
+ ActivityTypeIds::Type type = ActivityTypeIds::GetActivityType(type_id);
+ DCHECK_LT(type, ActivityTypeIds::ACTIVITY_MAX_VALUE);
+ return (1 << type);
+}
+
+} // namespace
+
+// static
+void MetricsService::RegisterPrefsAndroid(PrefRegistrySimple* registry) {
+ registry->RegisterIntegerPref(prefs::kStabilityForegroundActivityType,
+ ActivityTypeIds::ACTIVITY_NONE);
+ registry->RegisterIntegerPref(prefs::kStabilityLaunchedActivityFlags, 0);
+ registry->RegisterListPref(prefs::kStabilityLaunchedActivityCounts);
+ registry->RegisterListPref(prefs::kStabilityCrashedActivityCounts);
+}
+
+void MetricsService::LogAndroidStabilityToPrefs(PrefService* pref) {
+ // Track which Activities were launched by the user.
+ // A 'launch' is defined as starting the Activity at least once during a
+ // UMA session. Multiple launches are counted only once since it is possible
+ // for users to hop between Activities (e.g. entering and leaving Settings).
+ int launched = pref->GetInteger(prefs::kStabilityLaunchedActivityFlags);
+ ListPrefUpdate update_launches(pref, prefs::kStabilityLaunchedActivityCounts);
+ base::ListValue* launch_counts = update_launches.Get();
+ for (int activity_type = ActivityTypeIds::ACTIVITY_NONE;
+ activity_type < ActivityTypeIds::ACTIVITY_MAX_VALUE;
+ ++activity_type) {
+ if (launched & GetActivityFlag(activity_type))
+ IncrementListValue(launch_counts, activity_type);
+ }
+ pref->SetInteger(prefs::kStabilityLaunchedActivityFlags, 0);
+
+ // Track any Activities that were in the foreground when Chrome died.
+ // These Activities failed to be recorded as leaving the foreground, so Chrome
+ // couldn't have ended the UMA session cleanly. Record them as crashing.
+ int foreground = pref->GetInteger(prefs::kStabilityForegroundActivityType);
+ if (foreground != ActivityTypeIds::ACTIVITY_NONE) {
+ ListPrefUpdate update_crashes(pref, prefs::kStabilityCrashedActivityCounts);
+ base::ListValue* crash_counts = update_crashes.Get();
+ IncrementListValue(crash_counts, foreground);
+ pref->SetInteger(prefs::kStabilityForegroundActivityType,
+ ActivityTypeIds::ACTIVITY_NONE);
+ }
+
+ pref->CommitPendingWrite();
+}
+
+void MetricsService::ConvertAndroidStabilityPrefsToHistograms(
+ PrefService* pref) {
+ ListPrefUpdate launch_updater(pref, prefs::kStabilityLaunchedActivityCounts);
+ ListPrefUpdate crash_updater(pref, prefs::kStabilityCrashedActivityCounts);
+
+ base::ListValue* launch_counts = launch_updater.Get();
+ base::ListValue* crash_counts = crash_updater.Get();
+
+ for (int activity_type = ActivityTypeIds::ACTIVITY_NONE;
+ activity_type < ActivityTypeIds::ACTIVITY_MAX_VALUE;
+ ++activity_type) {
+ int launch_count = 0;
+ int crash_count = 0;
+
+ launch_counts->GetInteger(activity_type, &launch_count);
+ crash_counts->GetInteger(activity_type, &crash_count);
+
+ for (int count = 0; count < launch_count; ++count) {
+ UMA_STABILITY_HISTOGRAM_ENUMERATION(
+ "Chrome.Android.Activity.LaunchCounts",
+ activity_type,
+ ActivityTypeIds::ACTIVITY_MAX_VALUE);
+ }
+
+ for (int count = 0; count < crash_count; ++count) {
+ UMA_STABILITY_HISTOGRAM_ENUMERATION("Chrome.Android.Activity.CrashCounts",
+ activity_type,
+ ActivityTypeIds::ACTIVITY_MAX_VALUE);
+ }
+ }
+
+ launch_counts->Clear();
+ crash_counts->Clear();
+}
+
+void MetricsService::OnForegroundActivityChanged(PrefService* pref,
+ ActivityTypeIds::Type type) {
+ DCHECK(type < ActivityTypeIds::ACTIVITY_MAX_VALUE);
+
+ int activity_type = pref->GetInteger(prefs::kStabilityForegroundActivityType);
+ if (activity_type == type)
+ return;
+
+ // Record that the Activity is now in the foreground.
+ pref->SetInteger(prefs::kStabilityForegroundActivityType, type);
+
+ // Record that the Activity was launched this sesaion.
+ // The pref stores a set of flags ORed together, where each set flag
+ // corresponds to a launched Activity type.
+ int launched = pref->GetInteger(prefs::kStabilityLaunchedActivityFlags);
+ if (type != ActivityTypeIds::ACTIVITY_NONE) {
+ launched |= GetActivityFlag(type);
+ pref->SetInteger(prefs::kStabilityLaunchedActivityFlags, launched);
+ }
+
+ pref->CommitPendingWrite();
+}
+
+// static
+void MetricsService::DiscardOldStabilityStatsAndroid(PrefService* local_state) {
+ local_state->SetInteger(prefs::kStabilityForegroundActivityType,
+ ActivityTypeIds::ACTIVITY_NONE);
+ local_state->SetInteger(prefs::kStabilityLaunchedActivityFlags, 0);
+
+ ListPrefUpdate launches(local_state, prefs::kStabilityLaunchedActivityCounts);
+ launches.Get()->Clear();
+
+ ListPrefUpdate crashes(local_state, prefs::kStabilityCrashedActivityCounts);
+ crashes.Get()->Clear();
+}
diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp
index b3ea39d..1900034 100644
--- a/chrome/chrome.gyp
+++ b/chrome/chrome.gyp
@@ -981,6 +981,7 @@
'target_name': 'chrome_java',
'type': 'none',
'dependencies': [
+ 'activity_type_ids_java',
'chrome_resources.gyp:chrome_strings',
'profile_sync_service_model_type_selection_java',
'resource_id_java',
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index 8743fd0..7fd948e 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -100,6 +100,9 @@
'browser/accessibility/accessibility_events.h',
'browser/accessibility/invert_bubble_prefs.cc',
'browser/accessibility/invert_bubble_prefs.h',
+ 'browser/android/activity_type_id_list.h',
+ 'browser/android/activity_type_ids.cc',
+ 'browser/android/activity_type_ids.h',
'browser/android/banners/app_banner_settings_helper.cc',
'browser/android/banners/app_banner_settings_helper.h',
'browser/android/bookmarks/managed_bookmarks_shim.cc',
@@ -1234,6 +1237,7 @@
'browser/metrics/metrics_network_observer.h',
'browser/metrics/metrics_reporting_scheduler.cc',
'browser/metrics/metrics_reporting_scheduler.h',
+ 'browser/metrics/metrics_service_android.cc',
'browser/metrics/metrics_service.cc',
'browser/metrics/metrics_service.h',
'browser/metrics/perf_provider_chromeos.cc',
@@ -3719,6 +3723,18 @@
'includes': [ '../build/jni_generator.gypi' ],
},
{
+ 'target_name': 'activity_type_ids_java',
+ 'type': 'none',
+ 'sources': [
+ 'android/java/ActivityTypeIds.template',
+ ],
+ 'variables': {
+ 'package_name': 'org/chromium/chrome/browser',
+ 'template_deps': ['browser/android/activity_type_id_list.h'],
+ },
+ 'includes': [ '../build/android/java_cpp_template.gypi' ],
+ },
+ {
'target_name': 'resource_id_java',
'type': 'none',
'sources': [
diff --git a/chrome/common/metrics/metrics_service_base.cc b/chrome/common/metrics/metrics_service_base.cc
index 5f4edc2..66e8238 100644
--- a/chrome/common/metrics/metrics_service_base.cc
+++ b/chrome/common/metrics/metrics_service_base.cc
@@ -26,7 +26,14 @@ const char MetricsServiceBase::kMimeType[] = "application/vnd.chrome.uma";
void MetricsServiceBase::RecordCurrentHistograms() {
DCHECK(log_manager_.current_log());
- histogram_snapshot_manager_.PrepareDeltas(base::Histogram::kNoFlags, true);
+ histogram_snapshot_manager_.PrepareDeltas(
+ base::Histogram::kNoFlags, base::Histogram::kUmaTargetedHistogramFlag);
+}
+
+void MetricsServiceBase::RecordCurrentStabilityHistograms() {
+ DCHECK(log_manager_.current_log());
+ histogram_snapshot_manager_.PrepareDeltas(
+ base::Histogram::kNoFlags, base::Histogram::kUmaStabilityHistogramFlag);
}
void MetricsServiceBase::RecordDelta(
diff --git a/chrome/common/metrics/metrics_service_base.h b/chrome/common/metrics/metrics_service_base.h
index 24e73e7..f3a4a67 100644
--- a/chrome/common/metrics/metrics_service_base.h
+++ b/chrome/common/metrics/metrics_service_base.h
@@ -43,6 +43,10 @@ class MetricsServiceBase : public base::HistogramFlattener {
// Called when we close a log.
void RecordCurrentHistograms();
+ // Record complete list of stability histograms into the current log,
+ // i.e., histograms with the |kUmaStabilityHistogramFlag| flag set.
+ void RecordCurrentStabilityHistograms();
+
// Manager for the various in-flight logs.
MetricsLogManager log_manager_;
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc
index dc7ee69..baad881 100644
--- a/chrome/common/pref_names.cc
+++ b/chrome/common/pref_names.cc
@@ -1505,6 +1505,29 @@ const char kStabilityKernelCrashCount[] =
const char kStabilitySystemUncleanShutdownCount[] =
"user_experience_metrics.stability.system_unclean_shutdowns";
+#if defined(OS_ANDROID)
+// Activity type that is currently in the foreground for the UMA session.
+// Uses the ActivityTypeIds::Type enum.
+const char kStabilityForegroundActivityType[] =
+ "user_experience_metrics.stability.current_foreground_activity_type";
+
+// Tracks which Activities were launched during the last session.
+// See |metrics_service_android.cc| for its usage.
+const char kStabilityLaunchedActivityFlags[] =
+ "user_experience_metrics.stability.launched_activity_flags";
+
+// List pref: Counts how many times each Activity was launched.
+// Indexed into by ActivityTypeIds::Type.
+const char kStabilityLaunchedActivityCounts[] =
+ "user_experience_metrics.stability.launched_activity_counts";
+
+// List pref: Counts how many times each Activity type was in the foreground
+// when a UMA session failed to be shut down properly.
+// Indexed into by ActivityTypeIds::Type.
+const char kStabilityCrashedActivityCounts[] =
+ "user_experience_metrics.stability.crashed_activity_counts";
+#endif
+
// Number of times the browser has been able to register crash reporting.
const char kStabilityBreakpadRegistrationSuccess[] =
"user_experience_metrics.stability.breakpad_registration_ok";
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h
index 8c3e946..c069f1d 100644
--- a/chrome/common/pref_names.h
+++ b/chrome/common/pref_names.h
@@ -477,6 +477,12 @@ extern const char kStabilityChildProcessCrashCount[];
extern const char kStabilityOtherUserCrashCount[];
extern const char kStabilityKernelCrashCount[];
extern const char kStabilitySystemUncleanShutdownCount[];
+#if defined(OS_ANDROID)
+extern const char kStabilityForegroundActivityType[];
+extern const char kStabilityLaunchedActivityFlags[];
+extern const char kStabilityLaunchedActivityCounts[];
+extern const char kStabilityCrashedActivityCounts[];
+#endif
extern const char kStabilityBreakpadRegistrationSuccess[];
extern const char kStabilityBreakpadRegistrationFail[];
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index 977e434..eb1eab2 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -1436,6 +1436,22 @@ other types of suffix sets.
</summary>
</histogram>
+<histogram name="Chrome.Android.Activity.CrashCounts" enum="AndroidActivityId">
+ <summary>
+ Indicates how many times each particular type of Activity was in the
+ foreground when a UMA session was terminated abnormally. UMA sessions last
+ as long as Chrome remains in the foreground.
+ </summary>
+</histogram>
+
+<histogram name="Chrome.Android.Activity.LaunchCounts" enum="AndroidActivityId">
+ <summary>
+ Indicates how many times each particular type of Activity was brought to the
+ foreground when a UMA session was active (i.e. launched at some point). UMA
+ sessions last as long as Chrome remains in the foreground.
+ </summary>
+</histogram>
+
<histogram name="Chrome.Browser.CrashedExecutionPhase" enum="ExecutionPhase">
<summary>
Indicates the execution phase the browser was in when the browser crashed.
@@ -22547,6 +22563,14 @@ other types of suffix sets.
<int value="4" label="Snapped"/>
</enum>
+<enum name="AndroidActivityId" type="int">
+ <int value="1" label="Unknown"/>
+ <int value="2" label="Main"/>
+ <int value="3" label="Preferences"/>
+ <int value="4" label="WebappActivity"/>
+ <int value="5" label="FullScreenActivity"/>
+</enum>
+
<enum name="AndroidEvictionReason" type="int">
<int value="0" label="TabUnusedTooLong"/>
<int value="1" label="TabUnusedInSession"/>