diff options
author | rtenneti@chromium.org <rtenneti@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-04-29 05:42:22 +0000 |
---|---|---|
committer | rtenneti@chromium.org <rtenneti@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-04-29 05:42:22 +0000 |
commit | 63a8ba1e1fb71156beff23b4a26828dbc387c734 (patch) | |
tree | e69b6e1f24c5d7d1446bc6d5596518f44399bc67 /chrome | |
parent | dbf00c96e956033c1ea9b7542fa0d9c5ab1e66ac (diff) | |
download | chromium_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.cc | 8 | ||||
-rw-r--r-- | chrome/browser/metrics/field_trial_synchronizer.cc | 52 | ||||
-rw-r--r-- | chrome/browser/metrics/field_trial_synchronizer.h | 67 | ||||
-rw-r--r-- | chrome/chrome_browser.gypi | 2 | ||||
-rw-r--r-- | chrome/common/render_messages.h | 6 | ||||
-rw-r--r-- | chrome/renderer/chrome_render_process_observer.cc | 9 | ||||
-rw-r--r-- | chrome/renderer/chrome_render_process_observer.h | 4 |
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(); |