diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2019-05-16 09:59:13 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2019-05-20 10:28:53 +0000 |
commit | 6c11fb357ec39bf087b8b632e2b1e375aef1b38b (patch) | |
tree | c8315530db18a8ee566521c39ab8a6af4f72bc03 /chromium/components/variations | |
parent | 3ffaed019d0772e59d6cdb2d0d32fe4834c31f72 (diff) | |
download | qtwebengine-chromium-6c11fb357ec39bf087b8b632e2b1e375aef1b38b.tar.gz |
BASELINE: Update Chromium to 74.0.3729.159
Change-Id: I8d2497da544c275415aedd94dd25328d555de811
Reviewed-by: Michael BrĂ¼ning <michael.bruning@qt.io>
Diffstat (limited to 'chromium/components/variations')
30 files changed, 344 insertions, 434 deletions
diff --git a/chromium/components/variations/BUILD.gn b/chromium/components/variations/BUILD.gn index c764b7d13ea..5caa15ce040 100644 --- a/chromium/components/variations/BUILD.gn +++ b/chromium/components/variations/BUILD.gn @@ -21,8 +21,6 @@ static_library("variations") { "client_filterable_state.h", "entropy_provider.cc", "entropy_provider.h", - "experiment_labels.cc", - "experiment_labels.h", "hashing.cc", "hashing.h", "metrics.cc", @@ -49,8 +47,6 @@ static_library("variations") { "variations_associated_data.h", "variations_crash_keys.cc", "variations_crash_keys.h", - "variations_experiment_util.cc", - "variations_experiment_util.h", "variations_http_header_provider.cc", "variations_http_header_provider.h", "variations_id_collection.cc", @@ -103,12 +99,16 @@ if (is_android) { } android_library("load_seed_result_enum_java") { - deps = [ "//base:base_java" ] + deps = [ + "//base:base_java", + ] srcjar_deps = [ ":load_seed_result_enum_srcjar" ] } java_cpp_enum("load_seed_result_enum_srcjar") { - sources = [ "metrics.h" ] + sources = [ + "metrics.h", + ] } } @@ -135,7 +135,6 @@ source_set("unit_tests") { "active_field_trials_unittest.cc", "child_process_field_trial_syncer_unittest.cc", "entropy_provider_unittest.cc", - "experiment_labels_unittest.cc", "hashing_unittest.cc", "net/variations_command_line_unittest.cc", "net/variations_http_headers_unittest.cc", diff --git a/chromium/components/variations/android/java/src/org/chromium/components/variations/firstrun/VariationsSeedFetcher.java b/chromium/components/variations/android/java/src/org/chromium/components/variations/firstrun/VariationsSeedFetcher.java index 08081611f02..01054b79c19 100644 --- a/chromium/components/variations/android/java/src/org/chromium/components/variations/firstrun/VariationsSeedFetcher.java +++ b/chromium/components/variations/android/java/src/org/chromium/components/variations/firstrun/VariationsSeedFetcher.java @@ -6,6 +6,7 @@ package org.chromium.components.variations.firstrun; import android.content.SharedPreferences; import android.os.SystemClock; +import android.support.annotation.IntDef; import org.chromium.base.ContextUtils; import org.chromium.base.Log; @@ -17,6 +18,8 @@ import org.chromium.base.metrics.CachedMetrics.TimesHistogramSample; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.SocketTimeoutException; @@ -27,7 +30,6 @@ import java.text.SimpleDateFormat; import java.util.Arrays; import java.util.Date; import java.util.Locale; -import java.util.concurrent.TimeUnit; /** * Fetches the variations seed before the actual first run of Chrome. @@ -35,7 +37,12 @@ import java.util.concurrent.TimeUnit; public class VariationsSeedFetcher { private static final String TAG = "VariationsSeedFetch"; - public enum VariationsPlatform { ANDROID, ANDROID_WEBVIEW } + @IntDef({VariationsPlatform.ANDROID, VariationsPlatform.ANDROID_WEBVIEW}) + @Retention(RetentionPolicy.SOURCE) + public @interface VariationsPlatform { + int ANDROID = 0; + int ANDROID_WEBVIEW = 1; + } private static final String VARIATIONS_SERVER_URL = "https://clientservices.googleapis.com/chrome-variations/seed?osname="; @@ -85,7 +92,7 @@ public class VariationsSeedFetcher { @VisibleForTesting protected HttpURLConnection getServerConnection( - VariationsPlatform platform, String restrictMode, String milestone, String channel) + @VariationsPlatform int platform, String restrictMode, String milestone, String channel) throws MalformedURLException, IOException { String urlString = getConnectionString(platform, restrictMode, milestone, channel); URL url = new URL(urlString); @@ -93,14 +100,14 @@ public class VariationsSeedFetcher { } @VisibleForTesting - protected String getConnectionString( - VariationsPlatform platform, String restrictMode, String milestone, String channel) { + protected String getConnectionString(@VariationsPlatform int platform, String restrictMode, + String milestone, String channel) { String urlString = VARIATIONS_SERVER_URL; switch (platform) { - case ANDROID: + case VariationsPlatform.ANDROID: urlString += "android"; break; - case ANDROID_WEBVIEW: + case VariationsPlatform.ANDROID_WEBVIEW: urlString += "android_webview"; break; default: @@ -192,14 +199,14 @@ public class VariationsSeedFetcher { private void recordSeedFetchTime(long timeDeltaMillis) { Log.i(TAG, "Fetched first run seed in " + timeDeltaMillis + " ms"); - TimesHistogramSample histogram = new TimesHistogramSample( - "Variations.FirstRun.SeedFetchTime", TimeUnit.MILLISECONDS); + TimesHistogramSample histogram = + new TimesHistogramSample("Variations.FirstRun.SeedFetchTime"); histogram.record(timeDeltaMillis); } private void recordSeedConnectTime(long timeDeltaMillis) { - TimesHistogramSample histogram = new TimesHistogramSample( - "Variations.FirstRun.SeedConnectTime", TimeUnit.MILLISECONDS); + TimesHistogramSample histogram = + new TimesHistogramSample("Variations.FirstRun.SeedConnectTime"); histogram.record(timeDeltaMillis); } @@ -217,7 +224,7 @@ public class VariationsSeedFetcher { * connection. */ public SeedInfo downloadContent( - VariationsPlatform platform, String restrictMode, String milestone, String channel) + @VariationsPlatform int platform, String restrictMode, String milestone, String channel) throws SocketTimeoutException, UnknownHostException, IOException { HttpURLConnection connection = null; try { diff --git a/chromium/components/variations/entropy_provider.cc b/chromium/components/variations/entropy_provider.cc index 0c46368228a..d7eb868650f 100644 --- a/chromium/components/variations/entropy_provider.cc +++ b/chromium/components/variations/entropy_provider.cc @@ -37,8 +37,9 @@ double SHA1EntropyProvider::GetEntropyForTrial( // distribution given the same |trial_name|. When using such a low entropy // source, NormalizedMurmurHashEntropyProvider should be used instead. std::string input(entropy_source_); - input.append(randomization_seed == 0 ? trial_name : base::UintToString( - randomization_seed)); + input.append(randomization_seed == 0 + ? trial_name + : base::NumberToString(randomization_seed)); unsigned char sha1_hash[base::kSHA1Length]; base::SHA1HashBytes(reinterpret_cast<const unsigned char*>(input.c_str()), diff --git a/chromium/components/variations/entropy_provider_unittest.cc b/chromium/components/variations/entropy_provider_unittest.cc index de2ca1027db..79040f40cf3 100644 --- a/chromium/components/variations/entropy_provider_unittest.cc +++ b/chromium/components/variations/entropy_provider_unittest.cc @@ -91,7 +91,7 @@ class SHA1EntropyGenerator : public TrialEntropyGenerator { const int low_entropy_source = static_cast<uint16_t>(base::RandInt(0, kMaxLowEntropySize - 1)); const std::string high_entropy_source = - base::GenerateGUID() + base::IntToString(low_entropy_source); + base::GenerateGUID() + base::NumberToString(low_entropy_source); return GenerateSHA1Entropy(high_entropy_source, trial_name_); } diff --git a/chromium/components/variations/experiment_labels.cc b/chromium/components/variations/experiment_labels.cc deleted file mode 100644 index 1b0d85a5c96..00000000000 --- a/chromium/components/variations/experiment_labels.cc +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright 2014 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 "components/variations/experiment_labels.h" - -#include <vector> - -#include "base/logging.h" -#include "base/strings/string_number_conversions.h" -#include "base/strings/string_split.h" -#include "base/strings/string_util.h" -#include "base/strings/utf_string_conversions.h" -#include "components/variations/variations_associated_data.h" -#include "components/variations/variations_experiment_util.h" - -namespace variations { -namespace { - -const char kVariationPrefix[] = "CrVar"; - -} // namespace - -base::string16 ExtractNonVariationLabels(const base::string16& labels) { - // First, split everything by the label separator. - std::vector<base::StringPiece16> entries = base::SplitStringPiece( - labels, base::StringPiece16(&kExperimentLabelSeparator, 1), - base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); - - // For each label, keep the ones that do not look like a Variations label. - base::string16 non_variation_labels; - for (const base::StringPiece16& entry : entries) { - if (entry.empty() || - base::StartsWith(entry, - base::ASCIIToUTF16(kVariationPrefix), - base::CompareCase::INSENSITIVE_ASCII)) { - continue; - } - - // Dump the whole thing, including the timestamp. - if (!non_variation_labels.empty()) - non_variation_labels += kExperimentLabelSeparator; - entry.AppendToString(&non_variation_labels); - } - - return non_variation_labels; -} - -} // namespace variations diff --git a/chromium/components/variations/experiment_labels.h b/chromium/components/variations/experiment_labels.h deleted file mode 100644 index cd10825aa57..00000000000 --- a/chromium/components/variations/experiment_labels.h +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright 2014 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 COMPONENTS_VARIATIONS_EXPERIMENT_LABELS_H_ -#define COMPONENTS_VARIATIONS_EXPERIMENT_LABELS_H_ - -#include "base/metrics/field_trial.h" -#include "base/strings/string16.h" - -namespace variations { - -// Takes the value of experiment_labels from the registry and returns a valid -// experiment_labels string value containing only the labels that are not -// associated with Chrome Variations. -base::string16 ExtractNonVariationLabels(const base::string16& labels); - -} // namespace variations - -#endif // COMPONENTS_VARIATIONS_EXPERIMENT_LABELS_H_ diff --git a/chromium/components/variations/experiment_labels_unittest.cc b/chromium/components/variations/experiment_labels_unittest.cc deleted file mode 100644 index 797f57a82f8..00000000000 --- a/chromium/components/variations/experiment_labels_unittest.cc +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright 2014 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 "components/variations/experiment_labels.h" - -#include <stddef.h> - -#include <set> -#include <string> -#include <vector> - -#include "base/macros.h" -#include "base/metrics/field_trial.h" -#include "base/stl_util.h" -#include "base/strings/string_split.h" -#include "base/strings/utf_string_conversions.h" -#include "components/variations/variations_associated_data.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace variations { - -TEST(ExperimentLabelsTest, ExtractNonVariationLabels) { - struct { - const char* input_label; - const char* expected_output; - } test_cases[] = { - // Empty - {"", ""}, - // One - {"gcapi_brand=123|Tue, 21 Jan 2014 15:30:21 GMT", - "gcapi_brand=123|Tue, 21 Jan 2014 15:30:21 GMT"}, - // Three - {"CrVar1=123|Tue, 21 Jan 2014 15:30:21 GMT;" - "experiment1=456|Tue, 21 Jan 2014 15:30:21 GMT;" - "experiment2=789|Tue, 21 Jan 2014 15:30:21 GMT;" - "CrVar1=123|Tue, 21 Jan 2014 15:30:21 GMT", - "experiment1=456|Tue, 21 Jan 2014 15:30:21 GMT;" - "experiment2=789|Tue, 21 Jan 2014 15:30:21 GMT"}, - // One and one Variation - {"gcapi_brand=123|Tue, 21 Jan 2014 15:30:21 GMT;" - "CrVar1=3310002|Tue, 21 Jan 2014 15:30:21 GMT", - "gcapi_brand=123|Tue, 21 Jan 2014 15:30:21 GMT"}, - // One and one Variation, flipped - {"CrVar1=3310002|Tue, 21 Jan 2014 15:30:21 GMT;" - "gcapi_brand=123|Tue, 21 Jan 2014 15:30:21 GMT", - "gcapi_brand=123|Tue, 21 Jan 2014 15:30:21 GMT"}, - // Sandwiched - {"CrVar1=3310002|Tue, 21 Jan 2014 15:30:21 GMT;" - "gcapi_brand=123|Tue, 21 Jan 2014 15:30:21 GMT;" - "CrVar2=3310003|Tue, 21 Jan 2014 15:30:21 GMT;" - "CrVar3=3310004|Tue, 21 Jan 2014 15:30:21 GMT", - "gcapi_brand=123|Tue, 21 Jan 2014 15:30:21 GMT"}, - // Only Variations - {"CrVar1=3310002|Tue, 21 Jan 2014 15:30:21 GMT;" - "CrVar2=3310003|Tue, 21 Jan 2014 15:30:21 GMT;" - "CrVar3=3310004|Tue, 21 Jan 2014 15:30:21 GMT", - ""}, - // Empty values - {"gcapi_brand=123|Tue, 21 Jan 2014 15:30:21 GMT;" - "CrVar1=3310002|Tue, 21 Jan 2014 15:30:21 GMT", - "gcapi_brand=123|Tue, 21 Jan 2014 15:30:21 GMT"}, - // Trailing semicolon - {"gcapi_brand=123|Tue, 21 Jan 2014 15:30:21 GMT;" - "CrVar1=3310002|Tue, 21 Jan 2014 15:30:21 GMT;", // Note the semi here. - "gcapi_brand=123|Tue, 21 Jan 2014 15:30:21 GMT"}, - // Semis - {";;;;", ""}, - // Three non-Variation labels - // Testing that the order is preserved. - {"experiment1=456|Tue, 21 Jan 2014 15:30:21 GMT;" - "experiment2=789|Tue, 21 Jan 2014 15:30:21 GMT;" - "experiment3=123|Tue, 21 Jan 2014 15:30:21 GMT", - "experiment1=456|Tue, 21 Jan 2014 15:30:21 GMT;" - "experiment2=789|Tue, 21 Jan 2014 15:30:21 GMT;" - "experiment3=123|Tue, 21 Jan 2014 15:30:21 GMT"}, - }; - - for (size_t i = 0; i < base::size(test_cases); ++i) { - std::string non_variation_labels = base::UTF16ToUTF8( - ExtractNonVariationLabels( - base::ASCIIToUTF16(test_cases[i].input_label))); - EXPECT_EQ(test_cases[i].expected_output, non_variation_labels); - } -} - -} // namespace variations diff --git a/chromium/components/variations/net/variations_http_headers.cc b/chromium/components/variations/net/variations_http_headers.cc index 1b2eb27c137..c06fd473f75 100644 --- a/chromium/components/variations/net/variations_http_headers.cc +++ b/chromium/components/variations/net/variations_http_headers.cc @@ -6,8 +6,10 @@ #include <stddef.h> +#include <utility> #include <vector> +#include "base/bind.h" #include "base/macros.h" #include "base/metrics/histogram_macros.h" #include "base/stl_util.h" @@ -27,25 +29,9 @@ namespace variations { namespace { -const char* kSuffixesToSetHeadersFor[] = { - ".android.com", - ".doubleclick.com", - ".doubleclick.net", - ".ggpht.com", - ".googleadservices.com", - ".googleapis.com", - ".googlesyndication.com", - ".googleusercontent.com", - ".googlevideo.com", - ".gstatic.com", - ".litepages.googlezip.net", - ".ytimg.com", -}; - -// Exact hostnames in lowercase to set headers for. -const char* kHostsToSetHeadersFor[] = { - "googleweblight.com", -}; +// The name string for the header for variations information. +// Note that prior to M33 this header was named X-Chrome-Variations. +const char kClientDataHeader[] = "X-Client-Data"; // The result of checking if a URL should have variations headers appended. // This enum is used to record UMA histogram values, and should not be @@ -60,142 +46,194 @@ enum URLValidationResult { URL_VALIDATION_RESULT_SIZE, }; -// Checks whether headers should be appended to the |url|, based on the domain -// of |url|. |url| is assumed to be valid, and to have an http/https scheme. -bool IsGoogleDomain(const GURL& url) { - if (google_util::IsGoogleDomainUrl(url, google_util::ALLOW_SUBDOMAIN, - google_util::ALLOW_NON_STANDARD_PORTS)) { - return true; +void LogUrlValidationHistogram(URLValidationResult result) { + UMA_HISTOGRAM_ENUMERATION("Variations.Headers.URLValidationResult", result, + URL_VALIDATION_RESULT_SIZE); +} + +bool ShouldAppendVariationsHeader(const GURL& url) { + if (!url.is_valid()) { + LogUrlValidationHistogram(INVALID_URL); + return false; } - if (google_util::IsYoutubeDomainUrl(url, google_util::ALLOW_SUBDOMAIN, - google_util::ALLOW_NON_STANDARD_PORTS)) { - return true; + if (!url.SchemeIsHTTPOrHTTPS()) { + LogUrlValidationHistogram(NEITHER_HTTP_HTTPS); + return false; } + if (!google_util::IsGoogleAssociatedDomainUrl(url)) { + LogUrlValidationHistogram(NOT_GOOGLE_DOMAIN); + return false; + } + // We check https here, rather than before the IsGoogleDomain() check, to know + // how many Google domains are being rejected by the change to https only. + if (!url.SchemeIs(url::kHttpsScheme)) { + LogUrlValidationHistogram(IS_GOOGLE_NOT_HTTPS); + return false; + } + LogUrlValidationHistogram(SHOULD_APPEND); + return true; +} + +constexpr network::ResourceRequest* null_resource_request = nullptr; +constexpr net::URLRequest* null_url_request = nullptr; - // Some domains don't have international TLD extensions, so testing for them - // is very straight forward. - const std::string host = url.host(); - for (size_t i = 0; i < base::size(kSuffixesToSetHeadersFor); ++i) { - if (base::EndsWith(host, kSuffixesToSetHeadersFor[i], - base::CompareCase::INSENSITIVE_ASCII)) - return true; +class VariationsHeaderHelper { + public: + // Note: It's OK to pass SignedIn::kNo if it's unknown, as it does not affect + // transmission of experiments coming from the variations server. + VariationsHeaderHelper(network::ResourceRequest* request, + SignedIn signed_in = SignedIn::kNo) + : VariationsHeaderHelper(request, + null_url_request, + CreateVariationsHeader(signed_in)) {} + VariationsHeaderHelper(net::URLRequest* request, + SignedIn signed_in = SignedIn::kNo) + : VariationsHeaderHelper(null_resource_request, + request, + CreateVariationsHeader(signed_in)) {} + VariationsHeaderHelper(network::ResourceRequest* request, + const std::string& variations_header) + : VariationsHeaderHelper(request, null_url_request, variations_header) {} + + bool AppendHeaderIfNeeded(const GURL& url, InIncognito incognito) { + // Note the criteria for attaching client experiment headers: + // 1. We only transmit to Google owned domains which can evaluate + // experiments. + // 1a. These include hosts which have a standard postfix such as: + // *.doubleclick.net or *.googlesyndication.com or + // exactly www.googleadservices.com or + // international TLD domains *.google.<TLD> or *.youtube.<TLD>. + // 2. Only transmit for non-Incognito profiles. + // 3. For the X-Client-Data header, only include non-empty variation IDs. + if ((incognito == InIncognito::kYes) || !ShouldAppendVariationsHeader(url)) + return false; + + if (variations_header_.empty()) + return false; + + if (resource_request_) { + // Set the variations header to client_data_header rather than headers to + // be exempted from CORS checks. + resource_request_->client_data_header = variations_header_; + } else if (url_request_) { + url_request_->SetExtraRequestHeaderByName(kClientDataHeader, + variations_header_, false); + } else { + NOTREACHED(); + return false; + } + return true; } - for (size_t i = 0; i < base::size(kHostsToSetHeadersFor); ++i) { - if (base::LowerCaseEqualsASCII(host, kHostsToSetHeadersFor[i])) - return true; + + private: + static std::string CreateVariationsHeader(SignedIn signed_in) { + return VariationsHttpHeaderProvider::GetInstance()->GetClientDataHeader( + signed_in == SignedIn::kYes); } - return false; -} + VariationsHeaderHelper(network::ResourceRequest* resource_request, + net::URLRequest* url_request, + std::string variations_header) + : resource_request_(resource_request), url_request_(url_request) { + DCHECK(resource_request_ || url_request_); + variations_header_ = std::move(variations_header); + } -void LogUrlValidationHistogram(URLValidationResult result) { - UMA_HISTOGRAM_ENUMERATION("Variations.Headers.URLValidationResult", result, - URL_VALIDATION_RESULT_SIZE); -} + network::ResourceRequest* resource_request_; + net::URLRequest* url_request_; + std::string variations_header_; -// Removes variations headers for requests when a redirect to a non-Google URL -// occurs. This function is used as the callback parameter for -// SimpleURLLoader::SetOnRedirectCallback() when -// CreateSimpleURLLoaderWithVariationsHeaders() creates a SimpleURLLoader -// object. -void RemoveVariationsHeader(const net::RedirectInfo& redirect_info, - const network::ResourceResponseHead& response_head, - std::vector<std::string>* to_be_removed_headers) { - if (!ShouldAppendVariationHeaders(redirect_info.new_url)) - to_be_removed_headers->push_back(kClientDataHeader); -} + DISALLOW_COPY_AND_ASSIGN(VariationsHeaderHelper); +}; } // namespace -const char kClientDataHeader[] = "X-Client-Data"; +bool AppendVariationsHeader(const GURL& url, + InIncognito incognito, + SignedIn signed_in, + network::ResourceRequest* request) { + return VariationsHeaderHelper(request, signed_in) + .AppendHeaderIfNeeded(url, incognito); +} -bool AppendVariationHeaders(const GURL& url, +bool AppendVariationsHeader(const GURL& url, InIncognito incognito, SignedIn signed_in, - net::HttpRequestHeaders* headers) { - // Note the criteria for attaching client experiment headers: - // 1. We only transmit to Google owned domains which can evaluate experiments. - // 1a. These include hosts which have a standard postfix such as: - // *.doubleclick.net or *.googlesyndication.com or - // exactly www.googleadservices.com or - // international TLD domains *.google.<TLD> or *.youtube.<TLD>. - // 2. Only transmit for non-Incognito profiles. - // 3. For the X-Client-Data header, only include non-empty variation IDs. - if ((incognito == InIncognito::kYes) || !ShouldAppendVariationHeaders(url)) - return false; + net::URLRequest* request) { + return VariationsHeaderHelper(request, signed_in) + .AppendHeaderIfNeeded(url, incognito); +} - const std::string variation_ids_header = - VariationsHttpHeaderProvider::GetInstance()->GetClientDataHeader( - signed_in == SignedIn::kYes); - if (!variation_ids_header.empty()) { - // Note that prior to M33 this header was named X-Chrome-Variations. - headers->SetHeaderIfMissing(kClientDataHeader, variation_ids_header); - return true; - } - return false; +bool AppendVariationsHeaderWithCustomValue(const GURL& url, + InIncognito incognito, + const std::string& variations_header, + network::ResourceRequest* request) { + return VariationsHeaderHelper(request, variations_header) + .AppendHeaderIfNeeded(url, incognito); } -bool AppendVariationHeadersUnknownSignedIn(const GURL& url, +bool AppendVariationsHeaderUnknownSignedIn(const GURL& url, InIncognito incognito, - net::HttpRequestHeaders* headers) { - // Note: It's OK to pass SignedIn::kNo if it's unknown, as it does not affect - // transmission of experiments coming from the variations server. - return AppendVariationHeaders(url, incognito, SignedIn::kNo, headers); + network::ResourceRequest* request) { + return VariationsHeaderHelper(request).AppendHeaderIfNeeded(url, incognito); +} + +bool AppendVariationsHeaderUnknownSignedIn(const GURL& url, + InIncognito incognito, + net::URLRequest* request) { + return VariationsHeaderHelper(request).AppendHeaderIfNeeded(url, incognito); } -void StripVariationHeaderIfNeeded(const GURL& new_location, - net::URLRequest* request) { - if (!ShouldAppendVariationHeaders(new_location)) +void RemoveVariationsHeaderIfNeeded( + const net::RedirectInfo& redirect_info, + const network::ResourceResponseHead& response_head, + std::vector<std::string>* to_be_removed_headers) { + if (!ShouldAppendVariationsHeader(redirect_info.new_url)) + to_be_removed_headers->push_back(kClientDataHeader); +} + +void StripVariationsHeaderIfNeeded(const GURL& new_location, + net::URLRequest* request) { + if (!ShouldAppendVariationsHeader(new_location)) request->RemoveRequestHeaderByName(kClientDataHeader); } std::unique_ptr<network::SimpleURLLoader> -CreateSimpleURLLoaderWithVariationsHeaders( +CreateSimpleURLLoaderWithVariationsHeader( std::unique_ptr<network::ResourceRequest> request, InIncognito incognito, SignedIn signed_in, const net::NetworkTrafficAnnotationTag& annotation_tag) { - bool variation_headers_added = AppendVariationHeaders( - request->url, incognito, signed_in, &request->headers); + bool variation_headers_added = + AppendVariationsHeader(request->url, incognito, signed_in, request.get()); std::unique_ptr<network::SimpleURLLoader> simple_url_loader = network::SimpleURLLoader::Create(std::move(request), annotation_tag); if (variation_headers_added) { simple_url_loader->SetOnRedirectCallback( - base::BindRepeating(&RemoveVariationsHeader)); + base::BindRepeating(&RemoveVariationsHeaderIfNeeded)); } return simple_url_loader; } std::unique_ptr<network::SimpleURLLoader> -CreateSimpleURLLoaderWithVariationsHeadersUnknownSignedIn( +CreateSimpleURLLoaderWithVariationsHeaderUnknownSignedIn( std::unique_ptr<network::ResourceRequest> request, InIncognito incognito, const net::NetworkTrafficAnnotationTag& annotation_tag) { - return CreateSimpleURLLoaderWithVariationsHeaders( + return CreateSimpleURLLoaderWithVariationsHeader( std::move(request), incognito, SignedIn::kNo, annotation_tag); } -bool ShouldAppendVariationHeaders(const GURL& url) { - if (!url.is_valid()) { - LogUrlValidationHistogram(INVALID_URL); - return false; - } - if (!url.SchemeIsHTTPOrHTTPS()) { - LogUrlValidationHistogram(NEITHER_HTTP_HTTPS); - return false; - } - if (!IsGoogleDomain(url)) { - LogUrlValidationHistogram(NOT_GOOGLE_DOMAIN); - return false; - } - // We check https here, rather than before the IsGoogleDomain() check, to know - // how many Google domains are being rejected by the change to https only. - if (!url.SchemeIs("https")) { - LogUrlValidationHistogram(IS_GOOGLE_NOT_HTTPS); - return false; - } - LogUrlValidationHistogram(SHOULD_APPEND); - return true; +bool IsVariationsHeader(const std::string& header_name) { + return header_name == kClientDataHeader; +} + +bool HasVariationsHeader(const network::ResourceRequest& request) { + return !request.client_data_header.empty(); +} + +bool ShouldAppendVariationsHeaderForTesting(const GURL& url) { + return ShouldAppendVariationsHeader(url); } } // namespace variations diff --git a/chromium/components/variations/net/variations_http_headers.h b/chromium/components/variations/net/variations_http_headers.h index 4530a6d773f..a25f45d1c26 100644 --- a/chromium/components/variations/net/variations_http_headers.h +++ b/chromium/components/variations/net/variations_http_headers.h @@ -8,15 +8,17 @@ #include <memory> #include <set> #include <string> +#include <vector> namespace net { -class HttpRequestHeaders; struct NetworkTrafficAnnotationTag; +struct RedirectInfo; class URLRequest; } namespace network { struct ResourceRequest; +struct ResourceResponseHead; class SimpleURLLoader; } // namespace network @@ -28,10 +30,7 @@ enum class InIncognito { kNo, kYes }; enum class SignedIn { kNo, kYes }; -// The name string for the header for variations information. -extern const char kClientDataHeader[]; - -// Adds Chrome experiment and metrics state as custom headers to |headers|. +// Adds Chrome experiment and metrics state as custom headers to |request|. // The content of the headers will depend on |incognito| and |signed_in| // parameters. It is fine to pass SignedIn::NO if the state is not known to the // caller. This will prevent addition of ids of type @@ -39,46 +38,79 @@ extern const char kClientDataHeader[]; // from the variations server. These headers are never transmitted to non-Google // web sites, which is checked based on the destination |url|. // Returns true if custom headers are added. Returns false otherwise. -bool AppendVariationHeaders(const GURL& url, +bool AppendVariationsHeader(const GURL& url, + InIncognito incognito, + SignedIn signed_in, + network::ResourceRequest* request); + +// TODO(toyoshim): Remove this deprecated API that takes net::URLRequest* once +// all callers are removed after NetworkService being fully enabled, or migrated +// to use SimpleURLLoader. See, crbug.com/773295. +bool AppendVariationsHeader(const GURL& url, InIncognito incognito, SignedIn signed_in, - net::HttpRequestHeaders* headers); + net::URLRequest* request); + +// Similar to functions above, but uses specified |variations_header| as the +// custom header value. You should not generally need to use this. +bool AppendVariationsHeaderWithCustomValue(const GURL& url, + InIncognito incognito, + const std::string& variations_header, + network::ResourceRequest* request); -// Adds Chrome experiment and metrics state as custom headers to |headers| +// Adds Chrome experiment and metrics state as a custom header to |request| // when the signed-in state is not known to the caller; See above for details. -bool AppendVariationHeadersUnknownSignedIn(const GURL& url, +bool AppendVariationsHeaderUnknownSignedIn(const GURL& url, InIncognito incognito, - net::HttpRequestHeaders* headers); + network::ResourceRequest* request); -// Strips the variation header if |new_location| does not point to a location +// TODO(toyoshim): Remove this deprecated API that takes net::URLRequest* once +// all callers are removed after NetworkService being fully enabled, or migrated +// to use SimpleURLLoader. See, crbug.com/773295. +bool AppendVariationsHeaderUnknownSignedIn(const GURL& url, + InIncognito incognito, + net::URLRequest* request); + +// Removes the variations header for requests when a redirect to a non-Google +// URL occurs. +void RemoveVariationsHeaderIfNeeded( + const net::RedirectInfo& redirect_info, + const network::ResourceResponseHead& response_head, + std::vector<std::string>* to_be_removed_headers); + +// Strips the variations header if |new_location| does not point to a location // that should receive it. This is being called by the ChromeNetworkDelegate. -// Components calling AppendVariationsHeaders() don't need to take care of this. -void StripVariationHeaderIfNeeded(const GURL& new_location, - net::URLRequest* request); +// Components calling AppendVariationsHeader() don't need to take care of this. +void StripVariationsHeaderIfNeeded(const GURL& new_location, + net::URLRequest* request); -// Creates a SimpleURLLoader that will include variations headers for requests -// to Google and ensures they're removed if a redirect to a non-Google URL -// occurs. +// Creates a SimpleURLLoader that will include the variations header for +// requests to Google and ensures they're removed if a redirect to a non-Google +// URL occurs. std::unique_ptr<network::SimpleURLLoader> -CreateSimpleURLLoaderWithVariationsHeaders( +CreateSimpleURLLoaderWithVariationsHeader( std::unique_ptr<network::ResourceRequest> request, InIncognito incognito, SignedIn signed_in, const net::NetworkTrafficAnnotationTag& annotation_tag); -// Creates a SimpleURLLoader that will include variations headers for requests -// to Google when the signed-in state is unknown and ensures they're removed -// if a redirect to a non-Google URL occurs. +// Creates a SimpleURLLoader that will include the variations header for +// requests to Google when the signed-in state is unknown and ensures they're +// removed if a redirect to a non-Google URL occurs. std::unique_ptr<network::SimpleURLLoader> -CreateSimpleURLLoaderWithVariationsHeadersUnknownSignedIn( +CreateSimpleURLLoaderWithVariationsHeaderUnknownSignedIn( std::unique_ptr<network::ResourceRequest> request, InIncognito incognito, const net::NetworkTrafficAnnotationTag& annotation_tag); -// Checks whether variation headers should be appended to requests to the -// specified |url|. Returns true for google.<TLD> and youtube.<TLD> URLs with -// the https scheme. -bool ShouldAppendVariationHeaders(const GURL& url); +// Checks if |header_name| is one for the variations header. +bool IsVariationsHeader(const std::string& header_name); + +// Checks if |request| contains the variations header. +bool HasVariationsHeader(const network::ResourceRequest& request); + +// Calls the internal ShouldAppendVariationsHeader() for testing. +bool ShouldAppendVariationsHeaderForTesting(const GURL& url); } // namespace variations diff --git a/chromium/components/variations/net/variations_http_headers_unittest.cc b/chromium/components/variations/net/variations_http_headers_unittest.cc index 87dfc2dc533..a07883107ad 100644 --- a/chromium/components/variations/net/variations_http_headers_unittest.cc +++ b/chromium/components/variations/net/variations_http_headers_unittest.cc @@ -13,7 +13,7 @@ namespace variations { -TEST(VariationsHttpHeadersTest, ShouldAppendHeaders) { +TEST(VariationsHttpHeadersTest, ShouldAppendVariationsHeader) { struct { const char* url; bool should_append_headers; @@ -154,7 +154,8 @@ TEST(VariationsHttpHeadersTest, ShouldAppendHeaders) { for (size_t i = 0; i < base::size(cases); ++i) { const GURL url(cases[i].url); - EXPECT_EQ(cases[i].should_append_headers, ShouldAppendVariationHeaders(url)) + EXPECT_EQ(cases[i].should_append_headers, + ShouldAppendVariationsHeaderForTesting(url)) << url; } } diff --git a/chromium/components/variations/platform_field_trials.h b/chromium/components/variations/platform_field_trials.h index 3a7f64238f0..bb010fee9a6 100644 --- a/chromium/components/variations/platform_field_trials.h +++ b/chromium/components/variations/platform_field_trials.h @@ -29,6 +29,10 @@ class PlatformFieldTrials { bool has_seed, base::FeatureList* feature_list) = 0; + // Register any synthetic field trials. Will be called later than the above + // methods, in particular after g_browser_process is available.. + virtual void RegisterSyntheticTrials() {} + private: DISALLOW_COPY_AND_ASSIGN(PlatformFieldTrials); }; diff --git a/chromium/components/variations/processed_study.cc b/chromium/components/variations/processed_study.cc index e207ba4d75a..b8abc438682 100644 --- a/chromium/components/variations/processed_study.cc +++ b/chromium/components/variations/processed_study.cc @@ -55,11 +55,11 @@ bool ValidateStudyAndComputeTotalProbability( return false; } - // Note: This checks for ACTIVATION_EXPLICIT, since there is no reason to - // have this association with ACTIVATION_AUTO (where the trial starts + // Note: This checks for ACTIVATE_ON_QUERY, since there is no reason to + // have this association with ACTIVATE_ON_STARTUP (where the trial starts // active), as well as allowing flexibility to disable this behavior in the // future from the server by introducing a new activation type. - if (study.activation_type() == Study_ActivationType_ACTIVATION_EXPLICIT) { + if (study.activation_type() == Study_ActivationType_ACTIVATE_ON_QUERY) { const auto& features = experiment.feature_association(); for (int i = 0; i < features.enable_feature_size(); ++i) { features_to_associate.insert(features.enable_feature(i)); diff --git a/chromium/components/variations/proto/study.proto b/chromium/components/variations/proto/study.proto index 0169db04e26..0993802180c 100644 --- a/chromium/components/variations/proto/study.proto +++ b/chromium/components/variations/proto/study.proto @@ -334,10 +334,10 @@ message Study { enum ActivationType { // The study will be activated when its state is queried by the client. // This is recommended for most studies that include client code. - ACTIVATION_EXPLICIT = 0; + ACTIVATE_ON_QUERY = 0; // The study will be automatically activated when it is created. This // is recommended for studies that do not have any client logic. - ACTIVATION_AUTO = 1; + ACTIVATE_ON_STARTUP = 1; } // Activation type for this study. Defaults to ACTIVATION_EXPLICIT if omitted. diff --git a/chromium/components/variations/service/variations_field_trial_creator.cc b/chromium/components/variations/service/variations_field_trial_creator.cc index c1622956f5d..f98bbbcd0cb 100644 --- a/chromium/components/variations/service/variations_field_trial_creator.cc +++ b/chromium/components/variations/service/variations_field_trial_creator.cc @@ -15,6 +15,7 @@ #include <vector> #include "base/base_switches.h" +#include "base/bind.h" #include "base/build_time.h" #include "base/command_line.h" #include "base/metrics/histogram_functions.h" diff --git a/chromium/components/variations/service/variations_field_trial_creator_unittest.cc b/chromium/components/variations/service/variations_field_trial_creator_unittest.cc index c1088cdadb3..3910b35828c 100644 --- a/chromium/components/variations/service/variations_field_trial_creator_unittest.cc +++ b/chromium/components/variations/service/variations_field_trial_creator_unittest.cc @@ -30,7 +30,6 @@ #include "testing/gtest/include/gtest/gtest.h" #if defined(OS_ANDROID) -#include "components/variations/android/variations_seed_bridge.h" #include "components/variations/seed_response.h" #endif // OS_ANDROID @@ -99,6 +98,7 @@ VariationsSeed CreateTestSeedWithCountryFilter() { Study* study = seed.mutable_study(0); Study::Filter* filter = study->mutable_filter(); filter->add_country(kTestSeedCountry); + filter->add_platform(Study::PLATFORM_ANDROID); return seed; } diff --git a/chromium/components/variations/service/variations_service.cc b/chromium/components/variations/service/variations_service.cc index 6c53f8b5d2d..0583214e3de 100644 --- a/chromium/components/variations/service/variations_service.cc +++ b/chromium/components/variations/service/variations_service.cc @@ -25,6 +25,7 @@ #include "base/task/post_task.h" #include "base/task_runner_util.h" #include "base/timer/elapsed_timer.h" +#include "base/trace_event/trace_event.h" #include "base/values.h" #include "base/version.h" #include "build/build_config.h" @@ -502,11 +503,11 @@ bool VariationsService::DoFetchFromURL(const GURL& url, bool is_http_retry) { safe_seed_manager_.RecordFetchStarted(); - // Normally, there shouldn't be a |pending_request_| when this fires. However - // it's not impossible - for example if Chrome was paused (e.g. in a debugger - // or if the machine was suspended) and OnURLFetchComplete() hasn't had a - // chance to run yet from the previous request. In this case, don't start a - // new request and just let the previous one finish. + // Normally, there shouldn't be a |pending_seed_request_| when this fires. + // However it's not impossible - for example if Chrome was paused (e.g. in a + // debugger or if the machine was suspended) and OnURLFetchComplete() hasn't + // had a chance to run yet from the previous request. In this case, don't + // start a new request and just let the previous one finish. if (pending_seed_request_) return false; @@ -692,6 +693,7 @@ void VariationsService::OnSimpleLoaderRedirect( void VariationsService::OnSimpleLoaderCompleteOrRedirect( std::unique_ptr<std::string> response_body, bool was_redirect) { + TRACE_EVENT0("browser", "VariationsService::OnSimpleLoaderCompleteOrRedirect"); const bool is_first_request = !initial_request_completed_; initial_request_completed_ = true; @@ -918,6 +920,10 @@ void VariationsService::OverrideCachedUIStrings() { field_trial_creator_.OverrideCachedUIStrings(); } +void VariationsService::CancelCurrentRequestForTesting() { + pending_seed_request_.reset(); +} + std::string VariationsService::GetStoredPermanentCountry() { const base::ListValue* list_value = local_state_->GetList(prefs::kVariationsPermanentConsistencyCountry); diff --git a/chromium/components/variations/service/variations_service.h b/chromium/components/variations/service/variations_service.h index 217a7c56457..bc5fd826b0c 100644 --- a/chromium/components/variations/service/variations_service.h +++ b/chromium/components/variations/service/variations_service.h @@ -176,6 +176,11 @@ class VariationsService // Exposed for testing. void GetClientFilterableStateForVersionCalledForTesting(); + web_resource::ResourceRequestAllowedNotifier* + GetResourceRequestAllowedNotifierForTesting() { + return resource_request_allowed_notifier_.get(); + } + // Wrapper around VariationsFieldTrialCreator::SetupFieldTrials(). bool SetupFieldTrials(const char* kEnableGpuBenchmarking, const char* kEnableFeatures, @@ -190,6 +195,9 @@ class VariationsService int request_count() const { return request_count_; } + // Cancels the currently pending fetch request. + void CancelCurrentRequestForTesting(); + protected: // Starts the fetching process once, where |OnURLFetchComplete| is called with // the response. This calls DoFetchToURL with the set url. diff --git a/chromium/components/variations/service/variations_service_unittest.cc b/chromium/components/variations/service/variations_service_unittest.cc index 57eac53d3bb..0eb1a64ca37 100644 --- a/chromium/components/variations/service/variations_service_unittest.cc +++ b/chromium/components/variations/service/variations_service_unittest.cc @@ -11,12 +11,12 @@ #include <vector> #include "base/base64.h" +#include "base/bind.h" #include "base/feature_list.h" #include "base/json/json_string_value_serializer.h" #include "base/macros.h" #include "base/memory/ptr_util.h" #include "base/run_loop.h" -#include "base/sha1.h" #include "base/stl_util.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_split.h" diff --git a/chromium/components/variations/study_filtering.cc b/chromium/components/variations/study_filtering.cc index 6f1e21773de..54aa57b04e6 100644 --- a/chromium/components/variations/study_filtering.cc +++ b/chromium/components/variations/study_filtering.cc @@ -107,10 +107,6 @@ bool CheckStudyLocale(const Study::Filter& filter, const std::string& locale) { } bool CheckStudyPlatform(const Study::Filter& filter, Study::Platform platform) { - // An empty platform list matches all platforms. - if (filter.platform_size() == 0) - return true; - for (int i = 0; i < filter.platform_size(); ++i) { if (filter.platform(i) == platform) return true; diff --git a/chromium/components/variations/study_filtering_unittest.cc b/chromium/components/variations/study_filtering_unittest.cc index 184747fda93..2b11e1afc04 100644 --- a/chromium/components/variations/study_filtering_unittest.cc +++ b/chromium/components/variations/study_filtering_unittest.cc @@ -222,10 +222,10 @@ TEST(VariationsStudyFilteringTest, CheckStudyPlatform) { Study::Filter filter; // Check in the forwarded order. The loop cond is <= base::size(platforms) - // instead of < so that the result of adding the last channel gets checked. + // instead of < so that the result of adding the last platform gets checked. for (size_t i = 0; i <= base::size(platforms); ++i) { for (size_t j = 0; j < base::size(platforms); ++j) { - const bool expected = platform_added[j] || filter.platform_size() == 0; + const bool expected = platform_added[j]; const bool result = internal::CheckStudyPlatform(filter, platforms[j]); EXPECT_EQ(expected, result) << "Case " << i << "," << j << " failed!"; } @@ -241,7 +241,7 @@ TEST(VariationsStudyFilteringTest, CheckStudyPlatform) { memset(&platform_added, 0, sizeof(platform_added)); for (size_t i = 0; i <= base::size(platforms); ++i) { for (size_t j = 0; j < base::size(platforms); ++j) { - const bool expected = platform_added[j] || filter.platform_size() == 0; + const bool expected = platform_added[j]; const bool result = internal::CheckStudyPlatform(filter, platforms[j]); EXPECT_EQ(expected, result) << "Case " << i << "," << j << " failed!"; } @@ -575,6 +575,7 @@ TEST(VariationsStudyFilteringTest, FilterAndValidateStudiesWithCountry) { study->set_default_experiment_name("Default"); AddExperiment("Default", 100, study); study->set_consistency(test.consistency); + study->mutable_filter()->add_platform(Study::PLATFORM_ANDROID); if (test.filter_country) study->mutable_filter()->add_country(test.filter_country); if (test.filter_exclude_country) @@ -585,7 +586,7 @@ TEST(VariationsStudyFilteringTest, FilterAndValidateStudiesWithCountry) { client_state.reference_date = base::Time::Now(); client_state.version = base::Version("20.0.0.0"); client_state.channel = Study::STABLE; - client_state.form_factor = Study::DESKTOP; + client_state.form_factor = Study::PHONE; client_state.platform = Study::PLATFORM_ANDROID; client_state.session_consistency_country = kSessionCountry; client_state.permanent_consistency_country = kPermanentCountry; diff --git a/chromium/components/variations/variations_experiment_util.cc b/chromium/components/variations/variations_experiment_util.cc deleted file mode 100644 index 9cf78bbabc0..00000000000 --- a/chromium/components/variations/variations_experiment_util.cc +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright 2013 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 "components/variations/variations_experiment_util.h" - -#include <vector> - -#include "base/logging.h" -#include "base/strings/stringprintf.h" -#include "base/strings/utf_string_conversions.h" -#include "base/time/time.h" - -namespace variations { - -const base::char16 kExperimentLabelSeparator = ';'; - -namespace { - -const char* const kDays[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; - -const char* const kMonths[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; - -} // namespace - -base::string16 BuildExperimentDateString(const base::Time& current_time) { - // The Google Update experiment_labels timestamp format is: - // "DAY, DD0 MON YYYY HH0:MI0:SE0 TZ" - // DAY = 3 character day of week, - // DD0 = 2 digit day of month, - // MON = 3 character month of year, - // YYYY = 4 digit year, - // HH0 = 2 digit hour, - // MI0 = 2 digit minute, - // SE0 = 2 digit second, - // TZ = 3 character timezone - base::Time::Exploded then = {}; - current_time.UTCExplode(&then); - then.year += 1; - DCHECK(then.HasValidValues()); - - return base::UTF8ToUTF16( - base::StringPrintf("%s, %02d %s %d %02d:%02d:%02d GMT", - kDays[then.day_of_week], - then.day_of_month, - kMonths[then.month - 1], - then.year, - then.hour, - then.minute, - then.second)); -} - -} // namespace variations diff --git a/chromium/components/variations/variations_experiment_util.h b/chromium/components/variations/variations_experiment_util.h deleted file mode 100644 index c9c23f4006b..00000000000 --- a/chromium/components/variations/variations_experiment_util.h +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2013 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 COMPONENTS_VARIATIONS_VARIATIONS_EXPERIMENT_UTIL_H_ -#define COMPONENTS_VARIATIONS_VARIATIONS_EXPERIMENT_UTIL_H_ - -#include "base/strings/string16.h" - -namespace base { -class Time; -} - -namespace variations { - -// The separator used to separate items in experiment labels. -extern const base::char16 kExperimentLabelSeparator; - -// Constructs a date string in the format understood by Google Update for the -// |current_time| plus one year. -base::string16 BuildExperimentDateString(const base::Time& current_time); - -} // namespace variations - -#endif // COMPONENTS_VARIATIONS_VARIATIONS_EXPERIMENT_UTIL_H_ diff --git a/chromium/components/variations/variations_http_header_provider.cc b/chromium/components/variations/variations_http_header_provider.cc index 29084615b68..e8a1a389cbf 100644 --- a/chromium/components/variations/variations_http_header_provider.cc +++ b/chromium/components/variations/variations_http_header_provider.cc @@ -40,7 +40,7 @@ namespace variations { // ChromeContentBrowserClient::CreateURLLoaderThrottles() by also adding a // GoogleURLLoaderThrottle to a content::URLLoaderThrottle vector. // 3. SimpleURLLoader in browser, it is implemented in a SimpleURLLoader wrapper -// function variations::CreateSimpleURLLoaderWithVariationsHeaders(). +// function variations::CreateSimpleURLLoaderWithVariationsHeader(). // static VariationsHttpHeaderProvider* VariationsHttpHeaderProvider::GetInstance() { @@ -74,7 +74,7 @@ std::string VariationsHttpHeaderProvider::GetVariationsString() { base::AutoLock scoped_lock(lock_); for (const VariationIDEntry& entry : GetAllVariationIds()) { if (entry.second == GOOGLE_WEB_PROPERTIES) { - ids_string.append(base::IntToString(entry.first)); + ids_string.append(base::NumberToString(entry.first)); ids_string.push_back(' '); } } @@ -82,6 +82,28 @@ std::string VariationsHttpHeaderProvider::GetVariationsString() { return ids_string; } +std::vector<VariationID> VariationsHttpHeaderProvider::GetVariationsVector( + IDCollectionKey key) { + InitVariationIDsCacheIfNeeded(); + + // Get all the active variation ids while holding the lock. + std::set<VariationIDEntry> all_variation_ids; + { + base::AutoLock scoped_lock(lock_); + all_variation_ids = GetAllVariationIds(); + } + + // Copy the requested variations to the output vector. Note that the ids will + // be in sorted order because they're coming from a std::set. + std::vector<VariationID> result; + result.reserve(all_variation_ids.size()); + for (const VariationIDEntry& entry : all_variation_ids) { + if (entry.second == key) + result.push_back(entry.first); + } + return result; +} + VariationsHttpHeaderProvider::ForceIdsResult VariationsHttpHeaderProvider::ForceVariationIds( const std::vector<std::string>& variation_ids, diff --git a/chromium/components/variations/variations_http_header_provider.h b/chromium/components/variations/variations_http_header_provider.h index b29fcd07cdd..85b9d737d0d 100644 --- a/chromium/components/variations/variations_http_header_provider.h +++ b/chromium/components/variations/variations_http_header_provider.h @@ -57,6 +57,10 @@ class VariationsHttpHeaderProvider : public base::FieldTrialList::Observer, // a leading and trailing space, e.g. " 123 234 345 ". std::string GetVariationsString(); + // Returns the collection of of variation ids matching the given |key|. Each + // entry in the returned vector will be unique. + std::vector<VariationID> GetVariationsVector(IDCollectionKey key); + // Result of ForceVariationIds() call. enum class ForceIdsResult { SUCCESS, @@ -95,6 +99,8 @@ class VariationsHttpHeaderProvider : public base::FieldTrialList::Observer, OnFieldTrialGroupFinalized); FRIEND_TEST_ALL_PREFIXES(VariationsHttpHeaderProviderTest, GetVariationsString); + FRIEND_TEST_ALL_PREFIXES(VariationsHttpHeaderProviderTest, + GetVariationsVector); VariationsHttpHeaderProvider(); ~VariationsHttpHeaderProvider() override; diff --git a/chromium/components/variations/variations_http_header_provider_unittest.cc b/chromium/components/variations/variations_http_header_provider_unittest.cc index 70d1cbe8f4b..6e7823def3f 100644 --- a/chromium/components/variations/variations_http_header_provider_unittest.cc +++ b/chromium/components/variations/variations_http_header_provider_unittest.cc @@ -184,4 +184,25 @@ TEST_F(VariationsHttpHeaderProviderTest, GetVariationsString) { EXPECT_EQ(" 100 123 124 200 ", provider.GetVariationsString()); } +TEST_F(VariationsHttpHeaderProviderTest, GetVariationsVector) { + base::test::ScopedTaskEnvironment task_environment; + base::FieldTrialList field_trial_list(nullptr); + + CreateTrialAndAssociateId("t1", "g1", GOOGLE_WEB_PROPERTIES, 121); + CreateTrialAndAssociateId("t2", "g2", GOOGLE_WEB_PROPERTIES, 122); + CreateTrialAndAssociateId("t3", "g3", GOOGLE_WEB_PROPERTIES_TRIGGER, 123); + CreateTrialAndAssociateId("t4", "g4", GOOGLE_WEB_PROPERTIES_TRIGGER, 124); + CreateTrialAndAssociateId("t5", "g5", GOOGLE_WEB_PROPERTIES_SIGNED_IN, 125); + + VariationsHttpHeaderProvider provider; + provider.ForceVariationIds({"100", "200", "t101"}, ""); + + EXPECT_EQ((std::vector<VariationID>{100, 121, 122, 200}), + provider.GetVariationsVector(GOOGLE_WEB_PROPERTIES)); + EXPECT_EQ((std::vector<VariationID>{101, 123, 124}), + provider.GetVariationsVector(GOOGLE_WEB_PROPERTIES_TRIGGER)); + EXPECT_EQ((std::vector<VariationID>{125}), + provider.GetVariationsVector(GOOGLE_WEB_PROPERTIES_SIGNED_IN)); +} + } // namespace variations diff --git a/chromium/components/variations/variations_id_collection_unittest.cc b/chromium/components/variations/variations_id_collection_unittest.cc index a17343d9b65..2c4f4bbb5c9 100644 --- a/chromium/components/variations/variations_id_collection_unittest.cc +++ b/chromium/components/variations/variations_id_collection_unittest.cc @@ -7,6 +7,7 @@ #include <memory> #include <vector> +#include "base/bind.h" #include "base/metrics/field_trial.h" #include "base/run_loop.h" #include "base/test/scoped_task_environment.h" diff --git a/chromium/components/variations/variations_murmur_hash.h b/chromium/components/variations/variations_murmur_hash.h index 9ec77ad416e..b3e7458a82d 100644 --- a/chromium/components/variations/variations_murmur_hash.h +++ b/chromium/components/variations/variations_murmur_hash.h @@ -32,9 +32,9 @@ class VariationsMurmurHash { // it produces the same results that MurmurHash3_x86_32 would produce on a // little-endian platform. // - // |length| is the number of bytes to hash. It mustn't exceed - // padded_data.size() * 4. If length % 4 != 0, Hash will consume the - // less-significant bytes of the last uint32_t first. + // |length| is the number of bytes to hash. It mustn't exceed data.size() * 4. + // If length % 4 != 0, Hash will consume the less-significant bytes of the + // last uint32_t first. // // MurmurHash3_x86_32 takes a seed, for which 0 is the typical value. Hash // hard-codes the seed to 0, since NormalizedMurmurHashEntropyProvider doesn't diff --git a/chromium/components/variations/variations_request_scheduler_mobile.h b/chromium/components/variations/variations_request_scheduler_mobile.h index 5b46f1f1286..838373fb4ac 100644 --- a/chromium/components/variations/variations_request_scheduler_mobile.h +++ b/chromium/components/variations/variations_request_scheduler_mobile.h @@ -8,6 +8,7 @@ #include "base/bind.h" #include "base/gtest_prod_util.h" #include "base/macros.h" +#include "base/timer/timer.h" #include "components/variations/variations_request_scheduler.h" class PrefService; diff --git a/chromium/components/variations/variations_seed_processor.cc b/chromium/components/variations/variations_seed_processor.cc index 3bc232fdbdc..58e41585210 100644 --- a/chromium/components/variations/variations_seed_processor.cc +++ b/chromium/components/variations/variations_seed_processor.cc @@ -84,12 +84,12 @@ void ForceExperimentState( base::FieldTrial* trial) { RegisterExperimentParams(study, experiment); RegisterVariationIds(experiment, study.name()); - if (study.activation_type() == Study_ActivationType_ACTIVATION_AUTO) { + if (study.activation_type() == Study_ActivationType_ACTIVATE_ON_STARTUP) { // This call must happen after all params have been registered for the // trial. Otherwise, since we look up params by trial and group name, the // params won't be registered under the correct key. trial->group(); - // UI Strings can only be overridden from ACTIVATION_AUTO experiments. + // UI Strings can only be overridden from ACTIVATE_ON_STARTUP experiments. ApplyUIStringOverrides(experiment, override_callback); } } @@ -297,7 +297,7 @@ void VariationsSeedProcessor::CreateTrialFromStudy( if (enables_or_disables_features) RegisterFeatureOverrides(processed_study, trial.get(), feature_list); - if (study.activation_type() == Study_ActivationType_ACTIVATION_AUTO) { + if (study.activation_type() == Study_ActivationType_ACTIVATE_ON_STARTUP) { // This call must happen after all params have been registered for the // trial. Otherwise, since we look up params by trial and group name, the // params won't be registered under the correct key. @@ -308,7 +308,7 @@ void VariationsSeedProcessor::CreateTrialFromStudy( if (!has_overrides) return; - // UI Strings can only be overridden from ACTIVATION_AUTO experiments. + // UI Strings can only be overridden from ACTIVATE_ON_STARTUP experiments. int experiment_index = processed_study.GetExperimentIndexByName(group_name); // If the chosen experiment was not found in the study, simply return. // Although not normally expected, but could happen in exception cases, see diff --git a/chromium/components/variations/variations_seed_processor_unittest.cc b/chromium/components/variations/variations_seed_processor_unittest.cc index fcc5fb1c48f..f41d36ecc39 100644 --- a/chromium/components/variations/variations_seed_processor_unittest.cc +++ b/chromium/components/variations/variations_seed_processor_unittest.cc @@ -306,7 +306,7 @@ TEST_F(VariationsSeedProcessorTest, OverrideUIStrings) { Study study; study.set_name("Study1"); study.set_default_experiment_name("B"); - study.set_activation_type(Study_ActivationType_ACTIVATION_AUTO); + study.set_activation_type(Study_ActivationType_ACTIVATE_ON_STARTUP); Study_Experiment* experiment1 = AddExperiment("A", 0, &study); Study_Experiment_OverrideUIString* override = @@ -339,7 +339,7 @@ TEST_F(VariationsSeedProcessorTest, OverrideUIStringsWithForcingFlag) { Study study = CreateStudyWithFlagGroups(100, 0, 0); ASSERT_EQ(kForcingFlag1, study.experiment(1).forcing_flag()); - study.set_activation_type(Study_ActivationType_ACTIVATION_AUTO); + study.set_activation_type(Study_ActivationType_ACTIVATE_ON_STARTUP); Study_Experiment_OverrideUIString* override = study.mutable_experiment(1)->add_override_ui_string(); override->set_name_hash(1234); @@ -451,7 +451,7 @@ TEST_F(VariationsSeedProcessorTest, ValidateStudyWithAssociatedFeatures) { // Setting a different activation type should result in empty // |associated_features|. - study.set_activation_type(Study_ActivationType_ACTIVATION_AUTO); + study.set_activation_type(Study_ActivationType_ACTIVATE_ON_STARTUP); EXPECT_TRUE(processed_study.Init(&study, false)); EXPECT_THAT(processed_study.associated_features(), IsEmpty()); } @@ -539,14 +539,14 @@ TEST_F(VariationsSeedProcessorTest, StartsActive) { study2->set_default_experiment_name("Default"); AddExperiment("BB", 100, study2); AddExperiment("Default", 0, study2); - study2->set_activation_type(Study_ActivationType_ACTIVATION_AUTO); + study2->set_activation_type(Study_ActivationType_ACTIVATE_ON_STARTUP); Study* study3 = seed.add_study(); study3->set_name("C"); study3->set_default_experiment_name("Default"); AddExperiment("CC", 100, study3); AddExperiment("Default", 0, study3); - study3->set_activation_type(Study_ActivationType_ACTIVATION_EXPLICIT); + study3->set_activation_type(Study_ActivationType_ACTIVATE_ON_QUERY); ClientFilterableState client_state; client_state.locale = "en-CA"; @@ -561,8 +561,8 @@ TEST_F(VariationsSeedProcessorTest, StartsActive) { override_callback_.callback(), nullptr, &feature_list_); - // Non-specified and ACTIVATION_EXPLICIT should not start active, but - // ACTIVATION_AUTO should. + // Non-specified and ACTIVATE_ON_QUERY should not start active, but + // ACTIVATE_ON_STARTUP should. EXPECT_FALSE(base::FieldTrialList::IsTrialActive("A")); EXPECT_TRUE(base::FieldTrialList::IsTrialActive("B")); EXPECT_FALSE(base::FieldTrialList::IsTrialActive("C")); @@ -583,7 +583,7 @@ TEST_F(VariationsSeedProcessorTest, StartsActiveWithFlag) { base::FieldTrialList field_trial_list(nullptr); Study study = CreateStudyWithFlagGroups(100, 0, 0); - study.set_activation_type(Study_ActivationType_ACTIVATION_AUTO); + study.set_activation_type(Study_ActivationType_ACTIVATE_ON_STARTUP); EXPECT_TRUE(CreateTrialFromStudy(study)); EXPECT_TRUE(base::FieldTrialList::IsTrialActive(kFlagStudyName)); |