Update to current webrtc library

This is from the upstream library commit id
3326535126e435f1ba647885ce43a8f0f3d317eb, corresponding to Chromium
88.0.4290.1.
This commit is contained in:
Arun Raghavan
2020-10-12 18:08:02 -04:00
parent b1b02581d3
commit bcec8b0b21
859 changed files with 76187 additions and 49580 deletions

View File

@ -0,0 +1,247 @@
/*
* Copyright 2019 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "rtc_base/experiments/field_trial_parser.h"
#include <inttypes.h>
#include <algorithm>
#include <map>
#include <type_traits>
#include <utility>
#include "rtc_base/checks.h"
#include "rtc_base/logging.h"
#include "rtc_base/numerics/safe_conversions.h"
namespace webrtc {
namespace {
int FindOrEnd(std::string str, size_t start, char delimiter) {
size_t pos = str.find(delimiter, start);
pos = (pos == std::string::npos) ? str.length() : pos;
return static_cast<int>(pos);
}
} // namespace
FieldTrialParameterInterface::FieldTrialParameterInterface(std::string key)
: key_(key) {}
FieldTrialParameterInterface::~FieldTrialParameterInterface() {
RTC_DCHECK(used_) << "Field trial parameter with key: '" << key_
<< "' never used.";
}
void ParseFieldTrial(
std::initializer_list<FieldTrialParameterInterface*> fields,
std::string trial_string) {
std::map<std::string, FieldTrialParameterInterface*> field_map;
FieldTrialParameterInterface* keyless_field = nullptr;
for (FieldTrialParameterInterface* field : fields) {
field->MarkAsUsed();
if (!field->sub_parameters_.empty()) {
for (FieldTrialParameterInterface* sub_field : field->sub_parameters_) {
RTC_DCHECK(!sub_field->key_.empty());
sub_field->MarkAsUsed();
field_map[sub_field->key_] = sub_field;
}
continue;
}
if (field->key_.empty()) {
RTC_DCHECK(!keyless_field);
keyless_field = field;
} else {
field_map[field->key_] = field;
}
}
size_t i = 0;
while (i < trial_string.length()) {
int val_end = FindOrEnd(trial_string, i, ',');
int colon_pos = FindOrEnd(trial_string, i, ':');
int key_end = std::min(val_end, colon_pos);
int val_begin = key_end + 1;
std::string key = trial_string.substr(i, key_end - i);
absl::optional<std::string> opt_value;
if (val_end >= val_begin)
opt_value = trial_string.substr(val_begin, val_end - val_begin);
i = val_end + 1;
auto field = field_map.find(key);
if (field != field_map.end()) {
if (!field->second->Parse(std::move(opt_value))) {
RTC_LOG(LS_WARNING) << "Failed to read field with key: '" << key
<< "' in trial: \"" << trial_string << "\"";
}
} else if (!opt_value && keyless_field && !key.empty()) {
if (!keyless_field->Parse(key)) {
RTC_LOG(LS_WARNING) << "Failed to read empty key field with value '"
<< key << "' in trial: \"" << trial_string << "\"";
}
} else {
RTC_LOG(LS_INFO) << "No field with key: '" << key
<< "' (found in trial: \"" << trial_string << "\")";
std::string valid_keys;
for (const auto& f : field_map) {
valid_keys += f.first;
valid_keys += ", ";
}
RTC_LOG(LS_INFO) << "Valid keys are: " << valid_keys;
}
}
for (FieldTrialParameterInterface* field : fields) {
field->ParseDone();
}
}
template <>
absl::optional<bool> ParseTypedParameter<bool>(std::string str) {
if (str == "true" || str == "1") {
return true;
} else if (str == "false" || str == "0") {
return false;
}
return absl::nullopt;
}
template <>
absl::optional<double> ParseTypedParameter<double>(std::string str) {
double value;
char unit[2]{0, 0};
if (sscanf(str.c_str(), "%lf%1s", &value, unit) >= 1) {
if (unit[0] == '%')
return value / 100;
return value;
} else {
return absl::nullopt;
}
}
template <>
absl::optional<int> ParseTypedParameter<int>(std::string str) {
int64_t value;
if (sscanf(str.c_str(), "%" SCNd64, &value) == 1) {
if (rtc::IsValueInRangeForNumericType<int, int64_t>(value)) {
return static_cast<int>(value);
}
}
return absl::nullopt;
}
template <>
absl::optional<unsigned> ParseTypedParameter<unsigned>(std::string str) {
int64_t value;
if (sscanf(str.c_str(), "%" SCNd64, &value) == 1) {
if (rtc::IsValueInRangeForNumericType<unsigned, int64_t>(value)) {
return static_cast<unsigned>(value);
}
}
return absl::nullopt;
}
template <>
absl::optional<std::string> ParseTypedParameter<std::string>(std::string str) {
return std::move(str);
}
template <>
absl::optional<absl::optional<bool>> ParseTypedParameter<absl::optional<bool>>(
std::string str) {
return ParseOptionalParameter<bool>(str);
}
template <>
absl::optional<absl::optional<int>> ParseTypedParameter<absl::optional<int>>(
std::string str) {
return ParseOptionalParameter<int>(str);
}
template <>
absl::optional<absl::optional<unsigned>>
ParseTypedParameter<absl::optional<unsigned>>(std::string str) {
return ParseOptionalParameter<unsigned>(str);
}
template <>
absl::optional<absl::optional<double>>
ParseTypedParameter<absl::optional<double>>(std::string str) {
return ParseOptionalParameter<double>(str);
}
FieldTrialFlag::FieldTrialFlag(std::string key) : FieldTrialFlag(key, false) {}
FieldTrialFlag::FieldTrialFlag(std::string key, bool default_value)
: FieldTrialParameterInterface(key), value_(default_value) {}
bool FieldTrialFlag::Get() const {
return value_;
}
webrtc::FieldTrialFlag::operator bool() const {
return value_;
}
bool FieldTrialFlag::Parse(absl::optional<std::string> str_value) {
// Only set the flag if there is no argument provided.
if (str_value) {
absl::optional<bool> opt_value = ParseTypedParameter<bool>(*str_value);
if (!opt_value)
return false;
value_ = *opt_value;
} else {
value_ = true;
}
return true;
}
AbstractFieldTrialEnum::AbstractFieldTrialEnum(
std::string key,
int default_value,
std::map<std::string, int> mapping)
: FieldTrialParameterInterface(key),
value_(default_value),
enum_mapping_(mapping) {
for (auto& key_val : enum_mapping_)
valid_values_.insert(key_val.second);
}
AbstractFieldTrialEnum::AbstractFieldTrialEnum(const AbstractFieldTrialEnum&) =
default;
AbstractFieldTrialEnum::~AbstractFieldTrialEnum() = default;
bool AbstractFieldTrialEnum::Parse(absl::optional<std::string> str_value) {
if (str_value) {
auto it = enum_mapping_.find(*str_value);
if (it != enum_mapping_.end()) {
value_ = it->second;
return true;
}
absl::optional<int> value = ParseTypedParameter<int>(*str_value);
if (value.has_value() &&
(valid_values_.find(*value) != valid_values_.end())) {
value_ = *value;
return true;
}
}
return false;
}
template class FieldTrialParameter<bool>;
template class FieldTrialParameter<double>;
template class FieldTrialParameter<int>;
template class FieldTrialParameter<unsigned>;
template class FieldTrialParameter<std::string>;
template class FieldTrialConstrained<double>;
template class FieldTrialConstrained<int>;
template class FieldTrialConstrained<unsigned>;
template class FieldTrialOptional<double>;
template class FieldTrialOptional<int>;
template class FieldTrialOptional<unsigned>;
template class FieldTrialOptional<bool>;
template class FieldTrialOptional<std::string>;
} // namespace webrtc

View File

@ -0,0 +1,288 @@
/*
* Copyright 2018 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef RTC_BASE_EXPERIMENTS_FIELD_TRIAL_PARSER_H_
#define RTC_BASE_EXPERIMENTS_FIELD_TRIAL_PARSER_H_
#include <stdint.h>
#include <initializer_list>
#include <map>
#include <set>
#include <string>
#include <vector>
#include "absl/types/optional.h"
// Field trial parser functionality. Provides funcitonality to parse field trial
// argument strings in key:value format. Each parameter is described using
// key:value, parameters are separated with a ,. Values can't include the comma
// character, since there's no quote facility. For most types, white space is
// ignored. Parameters are declared with a given type for which an
// implementation of ParseTypedParameter should be provided. The
// ParseTypedParameter implementation is given whatever is between the : and the
// ,. If the key is provided without : a FieldTrialOptional will use nullopt.
// Example string: "my_optional,my_int:3,my_string:hello"
// For further description of usage and behavior, see the examples in the unit
// tests.
namespace webrtc {
class FieldTrialParameterInterface {
public:
virtual ~FieldTrialParameterInterface();
std::string key() const { return key_; }
protected:
// Protected to allow implementations to provide assignment and copy.
FieldTrialParameterInterface(const FieldTrialParameterInterface&) = default;
FieldTrialParameterInterface& operator=(const FieldTrialParameterInterface&) =
default;
explicit FieldTrialParameterInterface(std::string key);
friend void ParseFieldTrial(
std::initializer_list<FieldTrialParameterInterface*> fields,
std::string raw_string);
void MarkAsUsed() { used_ = true; }
virtual bool Parse(absl::optional<std::string> str_value) = 0;
virtual void ParseDone() {}
std::vector<FieldTrialParameterInterface*> sub_parameters_;
private:
std::string key_;
bool used_ = false;
};
// ParseFieldTrial function parses the given string and fills the given fields
// with extracted values if available.
void ParseFieldTrial(
std::initializer_list<FieldTrialParameterInterface*> fields,
std::string raw_string);
// Specialize this in code file for custom types. Should return absl::nullopt if
// the given string cannot be properly parsed.
template <typename T>
absl::optional<T> ParseTypedParameter(std::string);
// This class uses the ParseTypedParameter function to implement a parameter
// implementation with an enforced default value.
template <typename T>
class FieldTrialParameter : public FieldTrialParameterInterface {
public:
FieldTrialParameter(std::string key, T default_value)
: FieldTrialParameterInterface(key), value_(default_value) {}
T Get() const { return value_; }
operator T() const { return Get(); }
const T* operator->() const { return &value_; }
void SetForTest(T value) { value_ = value; }
protected:
bool Parse(absl::optional<std::string> str_value) override {
if (str_value) {
absl::optional<T> value = ParseTypedParameter<T>(*str_value);
if (value.has_value()) {
value_ = value.value();
return true;
}
}
return false;
}
private:
T value_;
};
// This class uses the ParseTypedParameter function to implement a parameter
// implementation with an enforced default value and a range constraint. Values
// outside the configured range will be ignored.
template <typename T>
class FieldTrialConstrained : public FieldTrialParameterInterface {
public:
FieldTrialConstrained(std::string key,
T default_value,
absl::optional<T> lower_limit,
absl::optional<T> upper_limit)
: FieldTrialParameterInterface(key),
value_(default_value),
lower_limit_(lower_limit),
upper_limit_(upper_limit) {}
T Get() const { return value_; }
operator T() const { return Get(); }
const T* operator->() const { return &value_; }
protected:
bool Parse(absl::optional<std::string> str_value) override {
if (str_value) {
absl::optional<T> value = ParseTypedParameter<T>(*str_value);
if (value && (!lower_limit_ || *value >= *lower_limit_) &&
(!upper_limit_ || *value <= *upper_limit_)) {
value_ = *value;
return true;
}
}
return false;
}
private:
T value_;
absl::optional<T> lower_limit_;
absl::optional<T> upper_limit_;
};
class AbstractFieldTrialEnum : public FieldTrialParameterInterface {
public:
AbstractFieldTrialEnum(std::string key,
int default_value,
std::map<std::string, int> mapping);
~AbstractFieldTrialEnum() override;
AbstractFieldTrialEnum(const AbstractFieldTrialEnum&);
protected:
bool Parse(absl::optional<std::string> str_value) override;
protected:
int value_;
std::map<std::string, int> enum_mapping_;
std::set<int> valid_values_;
};
// The FieldTrialEnum class can be used to quickly define a parser for a
// specific enum. It handles values provided as integers and as strings if a
// mapping is provided.
template <typename T>
class FieldTrialEnum : public AbstractFieldTrialEnum {
public:
FieldTrialEnum(std::string key,
T default_value,
std::map<std::string, T> mapping)
: AbstractFieldTrialEnum(key,
static_cast<int>(default_value),
ToIntMap(mapping)) {}
T Get() const { return static_cast<T>(value_); }
operator T() const { return Get(); }
private:
static std::map<std::string, int> ToIntMap(std::map<std::string, T> mapping) {
std::map<std::string, int> res;
for (const auto& it : mapping)
res[it.first] = static_cast<int>(it.second);
return res;
}
};
// This class uses the ParseTypedParameter function to implement an optional
// parameter implementation that can default to absl::nullopt.
template <typename T>
class FieldTrialOptional : public FieldTrialParameterInterface {
public:
explicit FieldTrialOptional(std::string key)
: FieldTrialParameterInterface(key) {}
FieldTrialOptional(std::string key, absl::optional<T> default_value)
: FieldTrialParameterInterface(key), value_(default_value) {}
absl::optional<T> GetOptional() const { return value_; }
const T& Value() const { return value_.value(); }
const T& operator*() const { return value_.value(); }
const T* operator->() const { return &value_.value(); }
explicit operator bool() const { return value_.has_value(); }
protected:
bool Parse(absl::optional<std::string> str_value) override {
if (str_value) {
absl::optional<T> value = ParseTypedParameter<T>(*str_value);
if (!value.has_value())
return false;
value_ = value.value();
} else {
value_ = absl::nullopt;
}
return true;
}
private:
absl::optional<T> value_;
};
// Equivalent to a FieldTrialParameter<bool> in the case that both key and value
// are present. If key is missing, evaluates to false. If key is present, but no
// explicit value is provided, the flag evaluates to true.
class FieldTrialFlag : public FieldTrialParameterInterface {
public:
explicit FieldTrialFlag(std::string key);
FieldTrialFlag(std::string key, bool default_value);
bool Get() const;
operator bool() const;
protected:
bool Parse(absl::optional<std::string> str_value) override;
private:
bool value_;
};
template <typename T>
absl::optional<absl::optional<T>> ParseOptionalParameter(std::string str) {
if (str.empty())
return absl::optional<T>();
auto parsed = ParseTypedParameter<T>(str);
if (parsed.has_value())
return parsed;
return absl::nullopt;
}
template <>
absl::optional<bool> ParseTypedParameter<bool>(std::string str);
template <>
absl::optional<double> ParseTypedParameter<double>(std::string str);
template <>
absl::optional<int> ParseTypedParameter<int>(std::string str);
template <>
absl::optional<unsigned> ParseTypedParameter<unsigned>(std::string str);
template <>
absl::optional<std::string> ParseTypedParameter<std::string>(std::string str);
template <>
absl::optional<absl::optional<bool>> ParseTypedParameter<absl::optional<bool>>(
std::string str);
template <>
absl::optional<absl::optional<int>> ParseTypedParameter<absl::optional<int>>(
std::string str);
template <>
absl::optional<absl::optional<unsigned>>
ParseTypedParameter<absl::optional<unsigned>>(std::string str);
template <>
absl::optional<absl::optional<double>>
ParseTypedParameter<absl::optional<double>>(std::string str);
// Accepts true, false, else parsed with sscanf %i, true if != 0.
extern template class FieldTrialParameter<bool>;
// Interpreted using sscanf %lf.
extern template class FieldTrialParameter<double>;
// Interpreted using sscanf %i.
extern template class FieldTrialParameter<int>;
// Interpreted using sscanf %u.
extern template class FieldTrialParameter<unsigned>;
// Using the given value as is.
extern template class FieldTrialParameter<std::string>;
extern template class FieldTrialConstrained<double>;
extern template class FieldTrialConstrained<int>;
extern template class FieldTrialConstrained<unsigned>;
extern template class FieldTrialOptional<double>;
extern template class FieldTrialOptional<int>;
extern template class FieldTrialOptional<unsigned>;
extern template class FieldTrialOptional<bool>;
extern template class FieldTrialOptional<std::string>;
} // namespace webrtc
#endif // RTC_BASE_EXPERIMENTS_FIELD_TRIAL_PARSER_H_