blob: a80e4de2b767109e5cea8d580abe2d6d4762dc0d [file] [log] [blame]
// Copyright 2016 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_VARIATIONS_CHILD_PROCESS_FIELD_TRIAL_SYNCER_H_
#define COMPONENTS_VARIATIONS_CHILD_PROCESS_FIELD_TRIAL_SYNCER_H_
#include <set>
#include <string>
#include "base/component_export.h"
#include "base/functional/callback.h"
#include "base/metrics/field_trial.h"
namespace variations {
// Provides functionality for child processes to sync the "activated" state of
// field trials between the child and browser. Specifically, when a field trial
// is activated in the browser, it also activates it in the child process and
// when a field trial is activated in the child process, it notifies the browser
// process to activate it.
//
// It also updates crash keys in the child process corresponding to the field
// trial state.
class COMPONENT_EXPORT(VARIATIONS) ChildProcessFieldTrialSyncer
: public base::FieldTrialList::Observer {
public:
using FieldTrialActivatedCallback =
base::RepeatingCallback<void(const std::string& trial_name)>;
// Creates and returns the global ChildProcessFieldTrialSyncer instance for
// this process. Immediately invokes |activated_callback| for each currently
// active field trial. Then, |activated_callback| is invoked as field trial
// are activated. |activated_callback| may be invoked from any sequence and
// must therefore be thread-safe. CreateInstance() must not be called
// concurrently with activating a field trial. The created instance is never
// destroyed because it would be difficult to ensure that no field trial is
// activated concurrently with unregistering it as an observer of
// FieldTrialList (see FieldTrialList::RemoveObserver).
static ChildProcessFieldTrialSyncer* CreateInstance(
FieldTrialActivatedCallback activated_callback);
// Testing variant which allows specifying a set of initially active trials.
static ChildProcessFieldTrialSyncer* CreateInstanceForTesting(
const std::set<std::string>& initially_active_trials,
FieldTrialActivatedCallback activated_callback);
ChildProcessFieldTrialSyncer(const ChildProcessFieldTrialSyncer&) = delete;
ChildProcessFieldTrialSyncer& operator=(const ChildProcessFieldTrialSyncer&) =
delete;
// Deletes the global ChildProcessFieldTrialSyncer instance.
static void DeleteInstanceForTesting();
// Must be invoked when the browser process notifies this child process that a
// field trial was activated.
void SetFieldTrialGroupFromBrowser(const std::string& trial_name,
const std::string& group_name);
private:
explicit ChildProcessFieldTrialSyncer(
FieldTrialActivatedCallback activated_callback);
~ChildProcessFieldTrialSyncer() override;
// Initializes field trial state change observation and invokes |callback_|
// for any field trials that might have already been activated according to
// `initially_active_trials`.
void Init(const std::set<std::string>& initially_active_trials);
// base::FieldTrialList::Observer:
void OnFieldTrialGroupFinalized(const base::FieldTrial& trial,
const std::string& group_name) override;
// Callback to invoke when a field trial is activated.
const FieldTrialActivatedCallback activated_callback_;
};
} // namespace variations
#endif // COMPONENTS_VARIATIONS_CHILD_PROCESS_FIELD_TRIAL_SYNCER_H_