summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorrtenneti@chromium.org <rtenneti@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-04-29 05:42:22 +0000
committerrtenneti@chromium.org <rtenneti@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-04-29 05:42:22 +0000
commit63a8ba1e1fb71156beff23b4a26828dbc387c734 (patch)
treee69b6e1f24c5d7d1446bc6d5596518f44399bc67 /chrome
parentdbf00c96e956033c1ea9b7542fa0d9c5ab1e66ac (diff)
downloadchromium_src-63a8ba1e1fb71156beff23b4a26828dbc387c734.zip
chromium_src-63a8ba1e1fb71156beff23b4a26828dbc387c734.tar.gz
chromium_src-63a8ba1e1fb71156beff23b4a26828dbc387c734.tar.bz2
Field trials are currently implemented (commonly) using a static variable that is set
once, the first time it is necessary to decide if there is an experiment by a given name active. With this change the field-test system can "push" a group that is selected for the given field trial (field test) if/when an experiment does arrive. This change implements a simple IPC notification of the result of a FieldTrial setting being sent to any previously started renderers. BUG=16494 TEST=field trial tests R=jar Review URL: http://codereview.chromium.org/6883029 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@83488 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/browser_main.cc8
-rw-r--r--chrome/browser/metrics/field_trial_synchronizer.cc52
-rw-r--r--chrome/browser/metrics/field_trial_synchronizer.h67
-rw-r--r--chrome/chrome_browser.gypi2
-rw-r--r--chrome/common/render_messages.h6
-rw-r--r--chrome/renderer/chrome_render_process_observer.cc9
-rw-r--r--chrome/renderer/chrome_render_process_observer.h4
7 files changed, 148 insertions, 0 deletions
diff --git a/chrome/browser/browser_main.cc b/chrome/browser/browser_main.cc
index d391bff..9b580b6 100644
--- a/chrome/browser/browser_main.cc
+++ b/chrome/browser/browser_main.cc
@@ -44,6 +44,7 @@
#include "chrome/browser/first_run/first_run_browser_process.h"
#include "chrome/browser/first_run/upgrade_util.h"
#include "chrome/browser/jankometer.h"
+#include "chrome/browser/metrics/field_trial_synchronizer.h"
#include "chrome/browser/metrics/histogram_synchronizer.h"
#include "chrome/browser/metrics/metrics_log.h"
#include "chrome/browser/metrics/metrics_service.h"
@@ -1330,6 +1331,13 @@ int BrowserMain(const MainFunctionParams& parameters) {
// field trials
parts->SetupFieldTrials();
+ // Initialize FieldTrialSynchronizer system. This is a singleton and is used
+ // for posting tasks via NewRunnableMethod. Its deleted when it goes out of
+ // scope. Even though NewRunnableMethod does AddRef and Release, the object
+ // will not be deleted after the Task is executed.
+ scoped_refptr<FieldTrialSynchronizer> field_trial_synchronizer(
+ new FieldTrialSynchronizer());
+
// Now that all preferences have been registered, set the install date
// for the uninstall metrics if this is our first run. This only actually
// gets used if the user has metrics reporting enabled at uninstall time.
diff --git a/chrome/browser/metrics/field_trial_synchronizer.cc b/chrome/browser/metrics/field_trial_synchronizer.cc
new file mode 100644
index 0000000..0e7484f
--- /dev/null
+++ b/chrome/browser/metrics/field_trial_synchronizer.cc
@@ -0,0 +1,52 @@
+// Copyright (c) 2011 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/field_trial_synchronizer.h"
+
+#include "base/logging.h"
+#include "base/threading/thread.h"
+#include "chrome/common/chrome_constants.h"
+#include "chrome/common/render_messages.h"
+#include "content/browser/browser_thread.h"
+#include "content/browser/renderer_host/render_process_host.h"
+
+FieldTrialSynchronizer::FieldTrialSynchronizer() {
+ DCHECK(field_trial_synchronizer_ == NULL);
+ field_trial_synchronizer_ = this;
+ base::FieldTrialList::AddObserver(this);
+}
+
+FieldTrialSynchronizer::~FieldTrialSynchronizer() {
+ base::FieldTrialList::RemoveObserver(this);
+ field_trial_synchronizer_ = NULL;
+}
+
+void FieldTrialSynchronizer::NotifyAllRenderers(
+ const std::string& field_trial_name,
+ const std::string& group_name) {
+ // To iterate over RenderProcessHosts, or to send messages to the hosts, we
+ // need to be on the UI thread.
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ for (RenderProcessHost::iterator it(RenderProcessHost::AllHostsIterator());
+ !it.IsAtEnd(); it.Advance()) {
+ it.GetCurrentValue()->Send(
+ new ViewMsg_SetFieldTrialGroup(field_trial_name, group_name));
+ }
+}
+
+void FieldTrialSynchronizer::OnFieldTrialGroupFinalized(
+ const std::string& field_trial_name,
+ const std::string& group_name) {
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ NewRunnableMethod(this,
+ &FieldTrialSynchronizer::NotifyAllRenderers,
+ field_trial_name,
+ group_name));
+}
+
+// static
+FieldTrialSynchronizer*
+ FieldTrialSynchronizer::field_trial_synchronizer_ = NULL;
diff --git a/chrome/browser/metrics/field_trial_synchronizer.h b/chrome/browser/metrics/field_trial_synchronizer.h
new file mode 100644
index 0000000..d72a75a
--- /dev/null
+++ b/chrome/browser/metrics/field_trial_synchronizer.h
@@ -0,0 +1,67 @@
+// Copyright (c) 2011 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_METRICS_FIELD_TRIAL_SYNCHRONIZER_H_
+#define CHROME_BROWSER_METRICS_FIELD_TRIAL_SYNCHRONIZER_H_
+#pragma once
+
+#include <string>
+#include <vector>
+
+#include "base/basictypes.h"
+#include "base/memory/ref_counted.h"
+#include "base/metrics/field_trial.h"
+
+class MessageLoop;
+class Task;
+
+// This class is used by the browser process to communicate FieldTrial setting
+// (field trial name and group) to any previously started renderers.
+//
+// This class registers itself as an observer of FieldTrialList. FieldTrialList
+// notifies this class by calling it's OnFieldTrialGroupFinalized method when a
+// group is selected (finalized) for a FieldTrial and OnFieldTrialGroupFinalized
+// method sends the FieldTrial's name and the group to all renderer processes.
+// Each renderer process creates the FieldTrial, and by using a 100% probability
+// for the FieldTrial, forces the FieldTrial to have the same group string.
+
+class FieldTrialSynchronizer
+ : public base::RefCountedThreadSafe<FieldTrialSynchronizer>,
+ public base::FieldTrialList::Observer {
+ public:
+ // Construction also sets up the global singleton instance. This instance is
+ // used to communicate between the UI and other threads, and is destroyed only
+ // as the main thread (browser_main) terminates, which means all other threads
+ // have completed, and will not need this instance any further. It adds itself
+ // as an observer of FieldTrialList so that it gets notified whenever a group
+ // is finalized in the browser process.
+ FieldTrialSynchronizer();
+
+ virtual ~FieldTrialSynchronizer();
+
+ // Notify all renderer processes about the |group_name| that is finalized for
+ // the given field trail (|field_trial_name|). This is called on UI thread.
+ void NotifyAllRenderers(const std::string& field_trial_name,
+ const std::string& group_name);
+
+ // FieldTrialList::Observer methods:
+
+ // This method is called by the FieldTrialList singleton when a trial's group
+ // is finalized. This method contacts all renderers (by calling
+ // NotifyAllRenderers) to create a FieldTrial that carries the randomly
+ // selected state from the browser process into all the renderer processes.
+ virtual void OnFieldTrialGroupFinalized(const std::string& name,
+ const std::string& group_name);
+
+ private:
+ // This singleton instance should be constructed during the single threaded
+ // portion of main(). It initializes globals to provide support for all future
+ // calls. This object is created on the UI thread, and it is destroyed after
+ // all the other threads have gone away.
+ static FieldTrialSynchronizer* field_trial_synchronizer_;
+
+ DISALLOW_COPY_AND_ASSIGN(FieldTrialSynchronizer);
+};
+
+#endif // CHROME_BROWSER_METRICS_FIELD_TRIAL_SYNCHRONIZER_H_
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index 15eed9f..da723a2 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -1277,6 +1277,8 @@
'browser/memory_details_win.cc',
'browser/memory_purger.cc',
'browser/memory_purger.h',
+ 'browser/metrics/field_trial_synchronizer.cc',
+ 'browser/metrics/field_trial_synchronizer.h',
'browser/metrics/histogram_synchronizer.cc',
'browser/metrics/histogram_synchronizer.h',
'browser/metrics/metric_event_duration_details.h',
diff --git a/chrome/common/render_messages.h b/chrome/common/render_messages.h
index b75ccb6..82b4e6a 100644
--- a/chrome/common/render_messages.h
+++ b/chrome/common/render_messages.h
@@ -201,6 +201,12 @@ IPC_MESSAGE_CONTROL0(ViewMsg_GetCacheResourceStats)
IPC_MESSAGE_CONTROL1(ViewMsg_GetRendererHistograms,
int /* sequence number of Renderer Histograms. */)
+// Tells the renderer to create a FieldTrial, and by using a 100% probability
+// for the FieldTrial, forces the FieldTrial to have assigned group name.
+IPC_MESSAGE_CONTROL2(ViewMsg_SetFieldTrialGroup,
+ std::string /* field trial name */,
+ std::string /* group name that was assigned. */)
+
#if defined(USE_TCMALLOC)
// Asks the renderer to send back tcmalloc stats.
IPC_MESSAGE_CONTROL0(ViewMsg_GetRendererTcmalloc)
diff --git a/chrome/renderer/chrome_render_process_observer.cc b/chrome/renderer/chrome_render_process_observer.cc
index ac54050..cfb98a7 100644
--- a/chrome/renderer/chrome_render_process_observer.cc
+++ b/chrome/renderer/chrome_render_process_observer.cc
@@ -6,6 +6,7 @@
#include "base/command_line.h"
#include "base/file_util.h"
+#include "base/metrics/field_trial.h"
#include "base/metrics/histogram.h"
#include "base/native_library.h"
#include "base/path_service.h"
@@ -390,6 +391,7 @@ bool ChromeRenderProcessObserver::OnControlMessageReceived(
OnSetContentSettingsForCurrentURL)
IPC_MESSAGE_HANDLER(ViewMsg_SetCacheCapacities, OnSetCacheCapacities)
IPC_MESSAGE_HANDLER(ViewMsg_ClearCache, OnClearCache)
+ IPC_MESSAGE_HANDLER(ViewMsg_SetFieldTrialGroup, OnSetFieldTrialGroup)
#if defined(USE_TCMALLOC)
IPC_MESSAGE_HANDLER(ViewMsg_GetRendererTcmalloc, OnGetRendererTcmalloc)
#endif
@@ -441,6 +443,12 @@ void ChromeRenderProcessObserver::OnGetRendererTcmalloc() {
}
#endif
+void ChromeRenderProcessObserver::OnSetFieldTrialGroup(
+ const std::string& field_trial_name,
+ const std::string& group_name) {
+ base::FieldTrialList::CreateFieldTrial(field_trial_name, group_name);
+}
+
void ChromeRenderProcessObserver::OnGetV8HeapStats() {
v8::HeapStatistics heap_stats;
v8::V8::GetHeapStatistics(&heap_stats);
@@ -476,3 +484,4 @@ void ChromeRenderProcessObserver::OnPurgeMemory() {
MallocExtension::instance()->ReleaseFreeMemory();
#endif
}
+
diff --git a/chrome/renderer/chrome_render_process_observer.h b/chrome/renderer/chrome_render_process_observer.h
index d40b502..844440b 100644
--- a/chrome/renderer/chrome_render_process_observer.h
+++ b/chrome/renderer/chrome_render_process_observer.h
@@ -6,6 +6,8 @@
#define CHROME_RENDERER_CHROME_RENDER_PROCESS_OBSERVER_H_
#pragma once
+#include <string>
+
#include "base/compiler_specific.h"
#include "content/renderer/render_process_observer.h"
@@ -35,6 +37,8 @@ class ChromeRenderProcessObserver : public RenderProcessObserver {
size_t capacity);
void OnClearCache();
void OnGetCacheResourceStats();
+ void OnSetFieldTrialGroup(const std::string& fiel_trial_name,
+ const std::string& group_name);
void OnGetRendererTcmalloc();
void OnGetV8HeapStats();
void OnPurgeMemory();