Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(772)

Unified Diff: components/contextual_suggestions/contextual_suggestions_service.cc

Issue 2965173002: Add ContextualSuggestionsService to Omnibox (Closed)
Patch Set: Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: components/contextual_suggestions/contextual_suggestions_service.cc
diff --git a/components/contextual_suggestions/contextual_suggestions_service.cc b/components/contextual_suggestions/contextual_suggestions_service.cc
new file mode 100644
index 0000000000000000000000000000000000000000..a04418e6591acf549578c3b0dce601f0b78bbad3
--- /dev/null
+++ b/components/contextual_suggestions/contextual_suggestions_service.cc
@@ -0,0 +1,194 @@
+// Copyright 2017 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/contextual_suggestions/contextual_suggestions_service.h"
+
+#include "base/feature_list.h"
+#include "base/memory/ptr_util.h"
+#include "base/metrics/field_trial_params.h"
+#include "base/strings/stringprintf.h"
+#include "components/contextual_suggestions/features.h"
+#include "components/data_use_measurement/core/data_use_user_data.h"
+#include "components/variations/net/variations_http_headers.h"
+#include "google_apis/gaia/gaia_constants.h"
+#include "net/base/escape.h"
+#include "net/base/load_flags.h"
+#include "net/http/http_response_headers.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
+#include "net/url_request/url_fetcher.h"
+
+namespace contextual_suggestions {
+
+namespace {
+
+// Parameter names used by the experiment redirecting Zero Suggestion requests
+// to a service provided by the Chrome team
+const char kZeroSuggestRedirectToChromeServerAddressParam[] =
+ "ZeroSuggestRedirectToChromeServerAddress";
+const char kZeroSuggestRedirectToChromeAdditionalFieldsParam[] =
+ "ZeroSuggestRedirectToChromeAdditionalFields";
+
+// Format string for OAuth2 authentication headers.
+const char kAuthorizationHeaderFormat[] = "Authorization: Bearer %s";
+
+} // namespace
+
+ContextualSuggestionsService::ContextualSuggestionsService(
+ SigninManagerBase* signin_manager,
+ OAuth2TokenService* token_service,
+ TemplateURLService* template_url_service,
+ net::URLRequestContextGetter* request_context)
+ : request_context_(request_context),
+ signin_manager_(signin_manager),
+ template_url_service_(template_url_service),
+ token_service_(token_service) {}
+
+ContextualSuggestionsService::~ContextualSuggestionsService() {}
+
+bool ContextualSuggestionsService::UseExperimentalZeroSuggestSuggestions()
+ const {
+ if (!base::FeatureList::IsEnabled(features::kZeroSuggestRedirectToChrome) ||
+ template_url_service_ == nullptr) {
+ return false;
+ }
+
+ // Check that the default search engine is Google.
+ const TemplateURL& default_provider_url =
+ *template_url_service_->GetDefaultSearchProvider();
+ const SearchTermsData& search_terms_data =
+ template_url_service_->search_terms_data();
+ if (default_provider_url.GetEngineType(search_terms_data) !=
+ SEARCH_ENGINE_GOOGLE) {
+ return false;
+ }
+
+ // Check that the suggest URL for redirect to chrome field trial is valid.
+ const GURL suggest_url =
+ ExperimentalZeroSuggestURL(/*visited_url=*/std::string());
+ if (!suggest_url.is_valid()) {
+ return false;
+ }
+
+ // Check that the suggest URL for redirect to chrome is HTTPS.
+ return suggest_url.SchemeIsCryptographic();
+}
+
+void ContextualSuggestionsService::CreateContextualSuggestionsRequest(
+ const std::string& visited_url,
+ net::URLFetcherDelegate* fetcher_delegate,
+ ContextualSuggestionsCallback callback) {
+ DCHECK(signin_manager_);
+ DCHECK(token_service_);
+
+ // Skip this request if still waiting for oauth2 token.
+ if (token_fetcher_) {
+ std::move(callback).Run(nullptr);
+ return;
+ }
+
+ std::unique_ptr<net::URLFetcher> fetcher =
+ CreateRequest(visited_url, fetcher_delegate);
+ if (fetcher == nullptr) {
+ std::move(callback).Run(nullptr);
+ return;
+ }
+
+ // Create the oauth2 token fetcher.
+ OAuth2TokenService::ScopeSet scopes{GaiaConstants::kAnyApiOAuth2Scope};
+ token_fetcher_ = base::MakeUnique<AccessTokenFetcher>(
+ "contextual_suggestions_service", signin_manager_, token_service_, scopes,
+ base::BindOnce(&ContextualSuggestionsService::AccessTokenAvailable,
+ base::Unretained(this), std::move(fetcher),
+ std::move(callback)));
+}
+
+// static
+GURL ContextualSuggestionsService::ExperimentalZeroSuggestURL(
+ const std::string& visited_url) {
+ const std::string server_address = base::GetFieldTrialParamValueByFeature(
+ features::kZeroSuggestRedirectToChrome,
+ kZeroSuggestRedirectToChromeServerAddressParam);
+ const std::string additional_parameters =
+ base::GetFieldTrialParamValueByFeature(
+ features::kZeroSuggestRedirectToChrome,
+ kZeroSuggestRedirectToChromeAdditionalFieldsParam);
+ return GURL(server_address + "/url=" + net::EscapePath(visited_url) +
+ additional_parameters);
+}
+
Mark P 2017/07/07 20:13:54 I'm a bit bothered that the whole rest of this fil
gcomanici 2017/07/07 21:24:45 I share the feeling with you and I am willing to m
+std::unique_ptr<net::URLFetcher> ContextualSuggestionsService::CreateRequest(
+ const std::string& visited_url,
+ net::URLFetcherDelegate* fetcher_delegate) const {
+ net::NetworkTrafficAnnotationTag traffic_annotation =
+ net::DefineNetworkTrafficAnnotation("omnibox_contextual_zerosuggest", R"(
Mark P 2017/07/07 20:13:54 Not sure if you should be using a new annotation h
gcomanici 2017/07/07 21:24:45 The annotation is different though. First, it send
+ semantics {
+ sender: "Omnibox"
+ description:
+ "When the user focuses the omnibox, Chrome can provide search or "
+ "navigation suggestions from the default search provider in the "
+ "omnibox dropdown, based on the current page URL.\n"
+ "This is limited to users whose default search engine is Google, "
+ "as no other search engines currently support this kind of "
+ "suggestion."
+ trigger: "The omnibox receives focus."
+ data: "The URL of the current page."
+ destination: GOOGLE_OWNED_SERVICE
+ }
+ policy {
+ cookies_allowed: false
+ setting:
+ "Users can control this feature via the 'Use a prediction service "
+ "to help complete searches and URLs typed in the address bar' "
+ "settings under 'Privacy'. The feature is enabled by default."
+ chrome_policy {
+ SearchSuggestEnabled {
+ policy_options {mode: MANDATORY}
+ SearchSuggestEnabled: false
+ }
+ }
+ })");
+ const int kFetcherID = 1;
+ const GURL suggest_url = ExperimentalZeroSuggestURL(visited_url);
+ DCHECK(suggest_url.is_valid());
+
+ std::unique_ptr<net::URLFetcher> fetcher =
+ net::URLFetcher::Create(kFetcherID, suggest_url, net::URLFetcher::GET,
+ fetcher_delegate, traffic_annotation);
+ data_use_measurement::DataUseUserData::AttachToFetcher(
+ fetcher.get(), data_use_measurement::DataUseUserData::OMNIBOX);
+ fetcher->SetRequestContext(request_context_);
+ fetcher->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES |
Mark P 2017/07/07 20:13:54 Are you sure you want to set this flag?
gcomanici 2017/07/07 21:24:46 The request sends the oauth token. As such, there
+ net::LOAD_DO_NOT_SAVE_COOKIES);
+ // Add Chrome experiment state to the request headers.
+ net::HttpRequestHeaders headers;
+ // Note: It's OK to pass |is_signed_in| false if it's unknown, as it does
+ // not affect transmission of experiments coming from the variations server.
+ variations::AppendVariationHeaders(fetcher->GetOriginalURL(),
+ /*incognito=*/false,
+ /*uma_enabled=*/false,
+ /*is_signed_in=*/false, &headers);
+ fetcher->SetExtraRequestHeaders(headers.ToString());
+ return fetcher;
+}
+
+void ContextualSuggestionsService::AccessTokenAvailable(
+ std::unique_ptr<net::URLFetcher> fetcher,
+ ContextualSuggestionsCallback callback,
+ const GoogleServiceAuthError& error,
+ const std::string& access_token) {
+ DCHECK(token_fetcher_);
+ std::unique_ptr<AccessTokenFetcher> token_fetcher_deleter(
+ std::move(token_fetcher_));
+
+ if (error.state() != GoogleServiceAuthError::NONE) {
+ std::move(callback).Run(nullptr);
+ return;
+ }
+ DCHECK(!access_token.empty());
+ fetcher->AddExtraRequestHeader(
+ base::StringPrintf(kAuthorizationHeaderFormat, access_token.c_str()));
+ std::move(callback).Run(std::move(fetcher));
+}
+
+} // namespace contextual_suggestions

Powered by Google App Engine
This is Rietveld 408576698