1// Copyright (c) 2012 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/metrics/field_trial_synchronizer.h"
6
7#include "base/bind.h"
8#include "base/logging.h"
9#include "base/threading/thread.h"
10#include "chrome/common/chrome_constants.h"
11#include "chrome/common/render_messages.h"
12#include "chrome/common/variations/variations_util.h"
13#include "content/public/browser/browser_thread.h"
14#include "content/public/browser/render_process_host.h"
15
16using content::BrowserThread;
17
18namespace {
19
20// This singleton instance should be constructed during the single threaded
21// portion of main(). It initializes globals to provide support for all future
22// calls. This object is created on the UI thread, and it is destroyed after
23// all the other threads have gone away.
24FieldTrialSynchronizer* g_field_trial_synchronizer = NULL;
25
26}  // namespace
27
28FieldTrialSynchronizer::FieldTrialSynchronizer() {
29  DCHECK(g_field_trial_synchronizer == NULL);
30  g_field_trial_synchronizer = this;
31  base::FieldTrialList::AddObserver(this);
32
33  chrome_variations::SetChildProcessLoggingVariationList();
34}
35
36void FieldTrialSynchronizer::NotifyAllRenderers(
37    const std::string& field_trial_name,
38    const std::string& group_name) {
39  // To iterate over RenderProcessHosts, or to send messages to the hosts, we
40  // need to be on the UI thread.
41  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
42
43  for (content::RenderProcessHost::iterator it(
44          content::RenderProcessHost::AllHostsIterator());
45       !it.IsAtEnd(); it.Advance()) {
46    it.GetCurrentValue()->Send(
47        new ChromeViewMsg_SetFieldTrialGroup(field_trial_name, group_name));
48  }
49}
50
51void FieldTrialSynchronizer::OnFieldTrialGroupFinalized(
52    const std::string& field_trial_name,
53    const std::string& group_name) {
54  CHECK(!field_trial_name.empty() && !group_name.empty());
55  BrowserThread::PostTask(
56      BrowserThread::UI, FROM_HERE,
57      base::Bind(&FieldTrialSynchronizer::NotifyAllRenderers,
58                 this,
59                 field_trial_name,
60                 group_name));
61  chrome_variations::SetChildProcessLoggingVariationList();
62}
63
64FieldTrialSynchronizer::~FieldTrialSynchronizer() {
65  base::FieldTrialList::RemoveObserver(this);
66  g_field_trial_synchronizer = NULL;
67}
68