Allow only one bookmark to be added for multiple fast starring
[chromium-blink-merge.git] / components / domain_reliability / config.cc
blob8c2935c37119bb66913fead4224addce2307d667
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 // Make sure stdint.h includes SIZE_MAX. (See C89, p259, footnote 221.)
6 #ifndef __STDC_LIMIT_MACROS
7 #define __STDC_LIMIT_MACROS 1
8 #endif
10 #include "components/domain_reliability/config.h"
12 #include <stdint.h>
14 #include "base/json/json_reader.h"
15 #include "base/json/json_value_converter.h"
16 #include "base/profiler/scoped_tracker.h"
17 #include "base/rand_util.h"
18 #include "base/strings/pattern.h"
19 #include "base/strings/string_util.h"
21 namespace {
23 bool ConvertURL(const base::StringPiece& string_piece, GURL* url) {
24 *url = GURL(string_piece.as_string());
25 return url->is_valid();
28 bool IsValidSampleRate(double p) { return p >= 0.0 && p <= 1.0; }
30 } // namespace
32 namespace domain_reliability {
34 // static
35 const size_t DomainReliabilityConfig::kInvalidResourceIndex = SIZE_MAX;
37 DomainReliabilityConfig::Resource::Resource() {
39 DomainReliabilityConfig::Resource::~Resource() {}
41 bool DomainReliabilityConfig::Resource::MatchesUrl(const GURL& url) const {
42 const std::string& spec = url.spec();
44 for (const auto& url_pattern : url_patterns) {
45 if (base::MatchPattern(spec, *url_pattern))
46 return true;
49 return false;
52 bool DomainReliabilityConfig::Resource::DecideIfShouldReportRequest(
53 bool success) const {
54 double sample_rate = success ? success_sample_rate : failure_sample_rate;
55 DCHECK(IsValidSampleRate(sample_rate));
56 return base::RandDouble() < sample_rate;
59 // static
60 void DomainReliabilityConfig::Resource::RegisterJSONConverter(
61 base::JSONValueConverter<DomainReliabilityConfig::Resource>* converter) {
62 converter->RegisterStringField("resource_name", &Resource::name);
63 converter->RegisterRepeatedString("url_patterns", &Resource::url_patterns);
64 converter->RegisterDoubleField("success_sample_rate",
65 &Resource::success_sample_rate);
66 converter->RegisterDoubleField("failure_sample_rate",
67 &Resource::failure_sample_rate);
70 bool DomainReliabilityConfig::Resource::IsValid() const {
71 return !name.empty() && !url_patterns.empty() &&
72 IsValidSampleRate(success_sample_rate) &&
73 IsValidSampleRate(failure_sample_rate);
76 DomainReliabilityConfig::Collector::Collector() {}
77 DomainReliabilityConfig::Collector::~Collector() {}
79 // static
80 void DomainReliabilityConfig::Collector::RegisterJSONConverter(
81 base::JSONValueConverter<DomainReliabilityConfig::Collector>* converter) {
82 converter->RegisterCustomField<GURL>("upload_url", &Collector::upload_url,
83 &ConvertURL);
86 bool DomainReliabilityConfig::Collector::IsValid() const {
87 return upload_url.is_valid();
90 DomainReliabilityConfig::DomainReliabilityConfig() : valid_until(0.0) {}
91 DomainReliabilityConfig::~DomainReliabilityConfig() {}
93 // static
94 scoped_ptr<const DomainReliabilityConfig> DomainReliabilityConfig::FromJSON(
95 const base::StringPiece& json) {
96 // TODO(vadimt): Remove ScopedTracker below once crbug.com/436671 is fixed.
97 tracked_objects::ScopedTracker tracking_profile(
98 FROM_HERE_WITH_EXPLICIT_FUNCTION(
99 "436671 DomainReliabilityConfig::FromJSON"));
100 scoped_ptr<base::Value> value = base::JSONReader::Read(json);
101 base::JSONValueConverter<DomainReliabilityConfig> converter;
102 scoped_ptr<DomainReliabilityConfig> config(new DomainReliabilityConfig());
104 // If we can parse and convert the JSON into a valid config, return that.
105 if (value && converter.Convert(*value, config.get()) && config->IsValid())
106 return config.Pass();
107 return scoped_ptr<const DomainReliabilityConfig>();
110 bool DomainReliabilityConfig::IsValid() const {
111 if (valid_until == 0.0 || domain.empty() ||
112 resources.empty() || collectors.empty()) {
113 return false;
116 for (auto& resource : resources) {
117 if (!resource->IsValid())
118 return false;
121 for (auto& collector : collectors) {
122 if (!collector->IsValid())
123 return false;
126 return true;
129 bool DomainReliabilityConfig::IsExpired(base::Time now) const {
130 DCHECK_NE(0.0, valid_until);
131 base::Time valid_until_time = base::Time::FromDoubleT(valid_until);
132 return now > valid_until_time;
135 size_t DomainReliabilityConfig::GetResourceIndexForUrl(const GURL& url) const {
136 // Removes username, password, and fragment.
137 GURL sanitized_url = url.GetAsReferrer();
139 for (size_t i = 0; i < resources.size(); ++i) {
140 if (resources[i]->MatchesUrl(sanitized_url))
141 return i;
144 return kInvalidResourceIndex;
147 // static
148 void DomainReliabilityConfig::RegisterJSONConverter(
149 base::JSONValueConverter<DomainReliabilityConfig>* converter) {
150 converter->RegisterStringField("config_version",
151 &DomainReliabilityConfig::version);
152 converter->RegisterDoubleField("config_valid_until",
153 &DomainReliabilityConfig::valid_until);
154 converter->RegisterStringField("monitored_domain",
155 &DomainReliabilityConfig::domain);
156 converter->RegisterRepeatedMessage("monitored_resources",
157 &DomainReliabilityConfig::resources);
158 converter->RegisterRepeatedMessage("collectors",
159 &DomainReliabilityConfig::collectors);
162 } // namespace domain_reliability