tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

field_trials.h (4272B)


      1 /*
      2 *  Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
      3 *
      4 *  Use of this source code is governed by a BSD-style license
      5 *  that can be found in the LICENSE file in the root of the source
      6 *  tree. An additional intellectual property rights grant can be found
      7 *  in the file PATENTS.  All contributing project authors may
      8 *  be found in the AUTHORS file in the root of the source tree.
      9 */
     10 
     11 #ifndef API_FIELD_TRIALS_H_
     12 #define API_FIELD_TRIALS_H_
     13 
     14 #include <atomic>
     15 #include <memory>
     16 #include <string>
     17 #include <utility>
     18 
     19 #include "absl/base/nullability.h"
     20 #include "absl/strings/string_view.h"
     21 #include "api/field_trials_registry.h"
     22 #include "api/field_trials_view.h"
     23 #include "rtc_base/checks.h"
     24 #include "rtc_base/containers/flat_map.h"
     25 
     26 namespace webrtc {
     27 
     28 // The FieldTrials class is used to inject field trials into webrtc.
     29 //
     30 // Field trials allow webrtc clients (such as Chromium) to turn on feature code
     31 // in binaries out in the field and gather information with that.
     32 //
     33 // They are designed to be easy to use with Chromium field trials and to speed
     34 // up developers by reducing the need to wire up APIs to control whether a
     35 // feature is on/off.
     36 //
     37 // The field trials are injected into objects that use them at creation time.
     38 class FieldTrials : public FieldTrialsRegistry {
     39 public:
     40  // Creates field trials from a valid field trial string.
     41  // Returns nullptr if the string is invalid.
     42  // E.g., valid string:
     43  //   "WebRTC-ExperimentFoo/Enabled/WebRTC-ExperimentBar/Enabled100kbps/"
     44  //   Assigns to group "Enabled" on WebRTC-ExperimentFoo trial
     45  //   and to group "Enabled100kbps" on WebRTC-ExperimentBar.
     46  //
     47  // E.g., invalid string:
     48  //   "WebRTC-experiment1/Enabled"  (note missing / separator at the end).
     49  static absl_nullable std::unique_ptr<FieldTrials> Create(absl::string_view s);
     50 
     51  // Creates field trials from a string.
     52  // It is an error to call the constructor with an invalid field trial string.
     53  explicit FieldTrials(absl::string_view s);
     54 
     55  FieldTrials(const FieldTrials&);
     56  FieldTrials(FieldTrials&&);
     57  FieldTrials& operator=(const FieldTrials&);
     58  FieldTrials& operator=(FieldTrials&&);
     59 
     60  ~FieldTrials() override = default;
     61 
     62  template <typename Sink>
     63  friend void AbslStringify(Sink& sink, const FieldTrials& self);
     64 
     65  // Merges field trials from the `other` into this.
     66  //
     67  // If a key (trial) exists twice with conflicting values (groups), the value
     68  // in `other` takes precedence.
     69  void Merge(const FieldTrials& other);
     70 
     71  // Sets value (`group`) for an indvidual `trial`.
     72  // It is an error to call this function with an invalid `trial` or `group`.
     73  // Setting empty `group` is valid and removes the `trial`.
     74  void Set(absl::string_view trial, absl::string_view group);
     75 
     76  // Create a copy of this view.
     77  std::unique_ptr<FieldTrialsView> CreateCopy() const override {
     78    // We don't need to reset get_value_called_ on the returned copy
     79    // since it is a FieldTrialsView that has no mutable methods.
     80    return std::make_unique<FieldTrials>(*this);
     81  }
     82 
     83  void AssertGetValueNotCalled() const {
     84 #if RTC_DCHECK_IS_ON
     85    RTC_DCHECK(!get_value_called_)
     86        << "FieldTrials are immutable once first Lookup has been performed";
     87 #endif
     88  }
     89 
     90 private:
     91  explicit FieldTrials(flat_map<std::string, std::string> key_value_map)
     92      : key_value_map_(std::move(key_value_map)) {}
     93 
     94  std::string GetValue(absl::string_view key) const override;
     95 
     96 #if RTC_DCHECK_IS_ON
     97  // Keep track of if GetValue() has been called.
     98  // This is used to enforce immutability by DCHECK:ing
     99  // that modification are performed once get_value_called_
    100  // is true.
    101  mutable std::atomic<bool> get_value_called_ = false;
    102 #endif
    103 
    104  flat_map<std::string, std::string> key_value_map_;
    105 };
    106 
    107 template <typename Sink>
    108 void AbslStringify(Sink& sink, const FieldTrials& self) {
    109  for (const auto& [trial, group] : self.key_value_map_) {
    110    sink.Append(trial);
    111    sink.Append("/");
    112    sink.Append(group);
    113    // Intentionally output a string that is not a valid field trial string.
    114    // Stringification is intended only for human readable logs, and is not
    115    // intended for reusing as `FieldTrials` construction parameter.
    116    sink.Append("//");
    117  }
    118 }
    119 
    120 }  // namespace webrtc
    121 
    122 #endif  // API_FIELD_TRIALS_H_