summaryrefslogtreecommitdiffstats
path: root/chrome/browser/metrics/metrics_reporting_state.cc
blob: c3d0fbb9e8192cb9073fa0b7571cc53856ffd6fb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
// Copyright (c) 2012 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_reporting_state.h"

#include "base/callback.h"
#include "base/metrics/histogram.h"
#include "base/prefs/pref_service.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/metrics/chrome_metrics_service_accessor.h"
#include "chrome/installer/util/google_update_settings.h"
#include "components/metrics/metrics_pref_names.h"
#include "components/metrics/metrics_service.h"
#include "content/public/browser/browser_thread.h"

#if defined(OS_CHROMEOS)
#include "chrome/browser/chromeos/settings/cros_settings.h"
#include "chromeos/settings/cros_settings_names.h"
#endif  // defined(OS_CHROMEOS)

namespace {

enum MetricsReportingChangeHistogramValue {
  METRICS_REPORTING_ERROR,
  METRICS_REPORTING_DISABLED,
  METRICS_REPORTING_ENABLED,
  METRICS_REPORTING_MAX
};

void RecordMetricsReportingHistogramValue(
    MetricsReportingChangeHistogramValue value) {
  UMA_HISTOGRAM_ENUMERATION(
      "UMA.MetricsReporting.Toggle", value, METRICS_REPORTING_MAX);
}

// Tries to set metrics reporting status to |enabled| and returns whatever is
// the result of the update.
bool SetGoogleUpdateSettings(bool enabled) {
  GoogleUpdateSettings::SetCollectStatsConsent(enabled);
  bool updated_pref = GoogleUpdateSettings::GetCollectStatsConsent();
  if (enabled != updated_pref)
    DVLOG(1) << "Unable to set metrics reporting status to " << enabled;

  return updated_pref;
}

// Does the necessary changes for MetricsReportingEnabled changes which needs
// to be done in the main thread.
// As arguments this function gets:
//  |to_update_pref| which indicates what the desired update should be,
//  |callback_fn| is the callback function to be called in the end
//  |updated_pref| is the result of attempted update.
// Update considers to be successful if |to_update_pref| and |updated_pref| are
// the same.
void SetMetricsReporting(bool to_update_pref,
                         const OnMetricsReportingCallbackType& callback_fn,
                         bool updated_pref) {
  metrics::MetricsService* metrics = g_browser_process->metrics_service();
  if (metrics) {
    if (updated_pref)
      metrics->Start();
    else
      metrics->Stop();
  }

#if !defined(OS_ANDROID)
  g_browser_process->local_state()->SetBoolean(
      metrics::prefs::kMetricsReportingEnabled, updated_pref);
#endif  // !defined(OS_ANDROID)

  // When a user opts in to the metrics reporting service, the previously
  // collected data should be cleared to ensure that nothing is reported before
  // a user opts in and all reported data is accurate.
  if (updated_pref && metrics)
    metrics->ClearSavedStabilityMetrics();

  if (to_update_pref == updated_pref) {
    RecordMetricsReportingHistogramValue(updated_pref ?
        METRICS_REPORTING_ENABLED : METRICS_REPORTING_DISABLED);
  } else {
    RecordMetricsReportingHistogramValue(METRICS_REPORTING_ERROR);
  }
  if (!callback_fn.is_null())
    callback_fn.Run(updated_pref);
}

#if defined(OS_CHROMEOS)
// Callback function for Chrome OS device settings change, so that the update is
// applied to metrics reporting state.
void OnDeviceSettingChange() {
  bool enable_metrics = false;
  chromeos::CrosSettings::Get()->GetBoolean(chromeos::kStatsReportingPref,
                                            &enable_metrics);
  InitiateMetricsReportingChange(enable_metrics,
                                 OnMetricsReportingCallbackType());
}
#endif

} // namespace

// TODO(gayane): Instead of checking policy before setting the metrics pref set
// the pref and register for notifications for the rest of the changes.
void InitiateMetricsReportingChange(
    bool enabled,
    const OnMetricsReportingCallbackType& callback_fn) {
#if !defined(OS_ANDROID)
  if (IsMetricsReportingPolicyManaged()) {
    if (!callback_fn.is_null()) {
      callback_fn.Run(
          ChromeMetricsServiceAccessor::IsMetricsAndCrashReportingEnabled());
    }
    return;
  }
#endif
  // Posts to FILE thread as SetGoogleUpdateSettings does IO operations.
  content::BrowserThread::PostTaskAndReplyWithResult(
      content::BrowserThread::FILE,
      FROM_HERE,
      base::Bind(&SetGoogleUpdateSettings, enabled),
      base::Bind(&SetMetricsReporting, enabled, callback_fn));
}

bool IsMetricsReportingPolicyManaged() {
  const PrefService* pref_service = g_browser_process->local_state();
  const PrefService::Preference* pref =
      pref_service->FindPreference(metrics::prefs::kMetricsReportingEnabled);
  return pref && pref->IsManaged();
}

// TODO(gayane): Add unittest which will check that observer on device settings
// will trigger this function and kMetricsReportinEnabled as well as metrics
// service state will be updated accordingly.
void SetupMetricsStateForChromeOS() {
#if defined(OS_CHROMEOS)
  chromeos::CrosSettings::Get()->AddSettingsObserver(
      chromeos::kStatsReportingPref, base::Bind(&OnDeviceSettingChange));

  OnDeviceSettingChange();
#endif // defined(OS_CHROMEOS)
}