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

Side by Side Diff: components/contextual_suggestions/contextual_suggestions_service.cc

Issue 2965173002: Add ContextualSuggestionsService to Omnibox (Closed)
Patch Set: Initial component creation 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2017 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.
4
5 #include "components/contextual_suggestions/contextual_suggestions_service.h"
6
7 #include "base/memory/ptr_util.h"
8 #include "base/metrics/field_trial_params.h"
9 #include "components/data_use_measurement/core/data_use_user_data.h"
10 #include "components/variations/net/variations_http_headers.h"
11 #include "google_apis/gaia/gaia_constants.h"
12 #include "net/base/escape.h"
13 #include "net/base/load_flags.h"
14 #include "net/http/http_response_headers.h"
15 #include "net/traffic_annotation/network_traffic_annotation.h"
16 #include "net/url_request/url_fetcher.h"
17
18 namespace contextual_suggestions {
19
20 namespace {
21
22 // Parameter names used by the experiment redirecting Zero Suggestion requests
23 // to a service provided by the Chrome team
24 const char kZeroSuggestRedirectToChromeServerAddressParam[] =
25 "ZeroSuggestRedirectToChromeServerAddress";
26 const char kZeroSuggestRedirectToChromeAdditionalFieldsParam[] =
27 "ZeroSuggestRedirectToChromeAdditionalFields";
28
29 // Format string for OAuth2 authentication headers.
30 const char kAuthorizationHeaderFormat[] = "Authorization: Bearer %s";
31
32 } // namespace
33
34 const base::Feature kZeroSuggestRedirectToChrome{
35 "ZeroSuggestRedirectToChrome", base::FEATURE_DISABLED_BY_DEFAULT};
36
37 ContextualSuggestionsService::ContextualSuggestionsService(
38 SigninManagerBase* signin_manager,
39 OAuth2TokenService* token_service,
40 TemplateURLService* template_url_service,
41 net::URLRequestContextGetter* request_context)
42 : signin_manager_(signin_manager),
43 token_service_(token_service),
44 template_url_service_(template_url_service),
45 request_context_(request_context) {}
46
47 ContextualSuggestionsService::~ContextualSuggestionsService() {}
48
49 bool ContextualSuggestionsService::UseExperimentalZeroSuggestSuggestions()
50 const {
51 if (!base::FeatureList::IsEnabled(kZeroSuggestRedirectToChrome) ||
52 template_url_service_ == nullptr)
53 return false;
Marc Treib 2017/07/06 08:32:20 nit: add braces if the condition doesn't fit on on
gcomanici 2017/07/06 15:34:17 Done.
54
55 // Check that the default search engine is Google.
56 const TemplateURL& default_provider_url =
57 *template_url_service_->GetDefaultSearchProvider();
58 const SearchTermsData& search_terms_data =
59 template_url_service_->search_terms_data();
60 if (default_provider_url.GetEngineType(search_terms_data) !=
61 SEARCH_ENGINE_GOOGLE)
62 return false;
Marc Treib 2017/07/06 08:32:20 Here too
gcomanici 2017/07/06 15:34:17 Done.
63
64 // Check that the suggest URL for redirect to chrome field trial is valid.
65 const GURL suggest_url =
66 ExperimentalZeroSuggestURL(/*visited_url=*/std::string());
67 if (!suggest_url.is_valid())
68 return false;
69
70 // Check that the suggest URL for redirect to chrome is HTTPS.
71 return suggest_url.SchemeIsCryptographic();
72 }
73
74 bool ContextualSuggestionsService::CreateContextualSuggestionsRequest(
75 const std::string& visited_url,
76 net::URLFetcherDelegate* fetcher_delegate,
77 ContextualSuggestionsCallback callback) {
78 DCHECK(signin_manager_);
79 DCHECK(token_service_);
80
81 // Skip this request is still waiting for oauth2 token.
Marc Treib 2017/07/06 08:32:20 s/is/if/ ?
gcomanici 2017/07/06 15:34:17 Done.
82 if (token_fetcher_)
83 return false;
84
85 std::unique_ptr<net::URLFetcher> fetcher =
86 CreateRequest(visited_url, fetcher_delegate);
87 if (fetcher == nullptr)
88 return false;
89
90 // Create the oauth2 token fetcher.
91 OAuth2TokenService::ScopeSet scopes{GaiaConstants::kAnyApiOAuth2Scope};
92 token_fetcher_ = base::MakeUnique<AccessTokenFetcher>(
93 "contextual_suggestions_service", signin_manager_, token_service_, scopes,
94 base::BindOnce(&ContextualSuggestionsService::AccessTokenAvailable,
95 base::Unretained(this), std::move(fetcher),
96 std::move(callback)));
97 return true;
98 }
99
100 // static
101 GURL ContextualSuggestionsService::ExperimentalZeroSuggestURL(
102 const std::string visited_url) {
103 const std::string server_address = base::GetFieldTrialParamValueByFeature(
104 kZeroSuggestRedirectToChrome,
105 kZeroSuggestRedirectToChromeServerAddressParam);
106 const std::string additional_parameters =
107 base::GetFieldTrialParamValueByFeature(
108 kZeroSuggestRedirectToChrome,
109 kZeroSuggestRedirectToChromeAdditionalFieldsParam);
110 return GURL(server_adddress + "/url=" + net::EscapePath(visited_url) +
111 additional_parameters);
112 }
113
114 std::unique_ptr<net::URLFetcher> ContextualSuggestionsService::CreateRequest(
115 const std::string& visited_url,
116 net::URLFetcherDelegate* fetcher_delegate) {
117 net::NetworkTrafficAnnotationTag traffic_annotation =
118 net::DefineNetworkTrafficAnnotation("omnibox_contextual_zerosuggest", R"(
119 semantics {
120 sender: "Omnibox"
121 description:
122 "When the user focuses the omnibox, Chrome can provide search or "
123 "navigation suggestions from the default search provider in the "
124 "omnibox dropdown, based on the current page URL.\n"
125 "This is limited to users whose default search engine is Google, "
126 "as no other search engines currently support this kind of "
127 "suggestion."
128 trigger: "The omnibox receives focus."
129 data: "The URL of the current page."
130 destination: GOOGLE_OWNED_SERVICE
131 }
132 policy {
133 cookies_allowed: true
Marc Treib 2017/07/06 08:32:20 Does this actually require cookies? If you're doin
gcomanici 2017/07/06 15:34:17 Good point. I was using the same annotation tag as
Marc Treib 2017/07/06 16:02:45 Ah, but then you also need to set net::LOAD_DO_NOT
gcomanici 2017/07/06 16:54:16 Done.
134 cookies_store: "user"
135 setting:
136 "Users can control this feature via the 'Use a prediction service "
137 "to help complete searches and URLs typed in the address bar' "
138 "settings under 'Privacy'. The feature is enabled by default."
139 chrome_policy {
140 SearchSuggestEnabled {
141 policy_options {mode: MANDATORY}
142 SearchSuggestEnabled: false
143 }
144 }
145 })");
146 const int kFetcherID = 1;
147 const GURL suggest_url = ExperimentalZeroSuggestURL(visited_url);
148 if (!suggest_url.is_valid())
Marc Treib 2017/07/06 08:32:20 If this were the case, we shouldn't get here, righ
gcomanici 2017/07/06 15:34:18 Added a DCHECK.
Marc Treib 2017/07/06 16:02:45 It's the wrong way around though ;)
gcomanici 2017/07/06 16:54:16 Fixed :)
149 return nullptr;
150
151 std::unique_ptr<net::URLFetcher> fetcher =
152 net::URLFetcher::Create(kFetcherID, suggest_url, net::URLFetcher::GET,
153 fetcher_delegate, traffic_annotation);
154 data_use_measurement::DataUseUserData::AttachToFetcher(
155 fetcher.get(), data_use_measurement::DataUseUserData::OMNIBOX);
156 fetcher->SetRequestContext(request_context_);
157 fetcher->SetLoadFlags(net::LOAD_DO_NOT_SAVE_COOKIES);
158 // Add Chrome experiment state to the request headers.
159 net::HttpRequestHeaders headers;
160 // Note: It's OK to pass |is_signed_in| false if it's unknown, as it does
161 // not affect transmission of experiments coming from the variations server.
162 variations::AppendVariationHeaders(fetcher->GetOriginalURL(),
163 /*incognito=*/false,
164 /*uma_enabled=*/false,
165 /*is_signed_in=*/false, &headers);
166 fetcher->SetExtraRequestHeaders(headers.ToString());
167 return fetcher;
168 }
169
170 void ContextualSuggestionsService::AccessTokenAvailable(
171 std::unique_ptr<net::URLFetcher> fetcher,
172 ContextualSuggestionsCallback callback,
173 const GoogleServiceAuthError& error,
174 const std::string& access_token) {
175 DCHECK(token_fetcher_);
176 std::unique_ptr<AccessTokenFetcher> token_fetcher_deleter(
177 std::move(token_fetcher_));
178
179 if (error.state() != GoogleServiceAuthError::NONE) {
180 return;
181 }
Marc Treib 2017/07/06 08:32:20 nit: Other places in this file don't use braces fo
gcomanici 2017/07/06 15:34:17 I chanced the other places for consistency.
182 DCHECK(!access_token.empty());
183 fetcher->AddExtraRequestHeader(
184 base::StringPrintf(kAuthorizationHeaderFormat, access_token.c_str()));
185 std::move(callback).Run(std::move(fetcher));
Marc Treib 2017/07/06 08:32:20 Is it okay to just not call the callback if someth
gcomanici 2017/07/06 15:34:17 I changed the description and signature for Create
186 }
187
188 } // namespace contextual_suggestions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698