blob: d75b0e7c07b5c28ae63f2708298a9c07451b7891 [file] [log] [blame]
Daniel Kenji Toyamaf1e4b572017-08-03 16:31:111// 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#ifndef COMPONENTS_OMNIBOX_BROWSER_CONTEXTUAL_SUGGESTIONS_SERVICE_H_
6#define COMPONENTS_OMNIBOX_BROWSER_CONTEXTUAL_SUGGESTIONS_SERVICE_H_
7
8#include <memory>
9#include <string>
10
Maks Orlovich1b208512018-06-13 21:08:1711#include "base/memory/scoped_refptr.h"
Daniel Kenji Toyamaf1e4b572017-08-03 16:31:1112#include "components/keyed_service/core/keyed_service.h"
Jenny Zhang5bc2e3d2018-09-10 18:50:5513#include "components/omnibox/browser/autocomplete_input.h"
Maks Orlovich1b208512018-06-13 21:08:1714#include "net/traffic_annotation/network_traffic_annotation.h"
Colin Blundell80bede82018-07-16 11:18:2715#include "services/identity/public/cpp/access_token_info.h"
Daniel Kenji Toyamaf1e4b572017-08-03 16:31:1116#include "url/gurl.h"
17
Jochen Eisinger4f96a312018-06-11 15:41:2618namespace base {
19class Time;
20}
21namespace identity {
22class IdentityManager;
23class PrimaryAccountAccessTokenFetcher;
24} // namespace identity
Jochen Eisinger4f96a312018-06-11 15:41:2625class GoogleServiceAuthError;
Daniel Kenji Toyamaf1e4b572017-08-03 16:31:1126class TemplateURLService;
27
Maks Orlovich1b208512018-06-13 21:08:1728namespace network {
29struct ResourceRequest;
30class SharedURLLoaderFactory;
31class SimpleURLLoader;
32} // namespace network
33
Daniel Kenji Toyamaf1e4b572017-08-03 16:31:1134// A service to fetch suggestions from a remote endpoint given a URL.
35class ContextualSuggestionsService : public KeyedService {
36 public:
Jochen Eisinger4f96a312018-06-11 15:41:2637 // |identity_manager| may be null but only unauthenticated requests will
38 // issued.
Maks Orlovich1b208512018-06-13 21:08:1739 ContextualSuggestionsService(
40 identity::IdentityManager* identity_manager,
41 scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory);
Daniel Kenji Toyamaf1e4b572017-08-03 16:31:1142
43 ~ContextualSuggestionsService() override;
44
Maks Orlovich1b208512018-06-13 21:08:1745 using StartCallback = base::OnceCallback<void(
46 std::unique_ptr<network::SimpleURLLoader> loader)>;
Daniel Kenji Toyamaf1e4b572017-08-03 16:31:1147
Maks Orlovich1b208512018-06-13 21:08:1748 using CompletionCallback =
49 base::OnceCallback<void(const network::SimpleURLLoader* source,
50 std::unique_ptr<std::string> response_body)>;
51
52 // Creates a loader for contextual suggestions for |current_url| and passes
53 // the loader to |start_callback|. It uses a number of signals to create the
54 // loader, including field trial / experimental parameters, and it may
55 // pass a nullptr to |start_callback| (see below for details).
Daniel Kenji Toyamaf1e4b572017-08-03 16:31:1156 //
57 // |current_url| may be empty, in which case the system will never use the
58 // experimental suggestions service. It's possible the non-experimental
59 // service may decide to offer general-purpose suggestions.
60 //
Gheorghe Comanici034cff62018-01-27 03:34:0061 // |visit_time| is the time of the visit for the URL for which suggestions
62 // should be fetched.
63 //
Jenny Zhang5bc2e3d2018-09-10 18:50:5564 // |input| is the current user input of the autocomplete query, whose
65 // |current_page_classification| will be used to build the suggestion url.
66 //
Daniel Kenji Toyamaf1e4b572017-08-03 16:31:1167 // |template_url_service| may be null, but some services may be disabled.
68 //
Maks Orlovich1b208512018-06-13 21:08:1769 // |start_callback| is called to transfer ownership of the created loader to
70 // whatever function/class receives the callback.
71 // |start_callback| is called with a nullptr argument if:
Daniel Kenji Toyamaf1e4b572017-08-03 16:31:1172 // * The service is waiting for a previously-requested authentication token.
73 // * The authentication token had any issues.
74 //
Maks Orlovich1b208512018-06-13 21:08:1775 // |completion_callback| will be invoked when the transfer is done.
76 //
Daniel Kenji Toyamaf1e4b572017-08-03 16:31:1177 // This method sends a request for an OAuth2 token and temporarily
78 // instantiates |token_fetcher_|.
79 void CreateContextualSuggestionsRequest(
80 const std::string& current_url,
Gheorghe Comanici034cff62018-01-27 03:34:0081 const base::Time& visit_time,
Jenny Zhang5bc2e3d2018-09-10 18:50:5582 const AutocompleteInput& input,
Daniel Kenji Toyamaf1e4b572017-08-03 16:31:1183 const TemplateURLService* template_url_service,
Maks Orlovich1b208512018-06-13 21:08:1784 StartCallback start_callback,
85 CompletionCallback completion_callback);
Daniel Kenji Toyamaf1e4b572017-08-03 16:31:1186
Gheorghe Comanici86bbdf62017-08-28 17:20:3387 // Advises the service to stop any process that creates a suggestion request.
88 void StopCreatingContextualSuggestionsRequest();
89
Daniel Kenji Toyamaf1e4b572017-08-03 16:31:1190 // Returns a URL representing the address of the server where the zero suggest
91 // request is being sent. Does not take into account whether sending this
92 // request is prohibited (e.g. in an incognito window).
93 // Returns an invalid URL (i.e.: GURL::is_valid() == false) in case of an
94 // error.
95 //
96 // |current_url| is the page the user is currently browsing and may be empty.
97 //
Jenny Zhang5bc2e3d2018-09-10 18:50:5598 // |input| is the current user input of the autocomplete query, whose
99 // |current_page_classification| will be used to build the suggestion url.
100 //
Daniel Kenji Toyamaf1e4b572017-08-03 16:31:11101 // Note that this method is public and is also used by ZeroSuggestProvider for
102 // suggestions that do not take |current_url| into consideration.
103 static GURL ContextualSuggestionsUrl(
104 const std::string& current_url,
Jenny Zhang5bc2e3d2018-09-10 18:50:55105 const AutocompleteInput& input,
Daniel Kenji Toyamaf1e4b572017-08-03 16:31:11106 const TemplateURLService* template_url_service);
107
108 private:
109 // Returns a URL representing the address of the server where the zero suggest
110 // requests are being redirected when serving experimental suggestions.
111 //
112 // Returns a valid URL only if all the folowing conditions are true:
113 // * The |current_url| is non-empty.
114 // * The |default_provider| is Google.
115 // * The user is in the ZeroSuggestRedirectToChrome field trial.
116 // * The field trial provides a valid server address where the suggest request
117 // is redirected.
118 // * The suggest request is over HTTPS. This avoids leaking the current page
119 // URL or personal data in unencrypted network traffic.
120 // Note: these checks are in addition to CanSendUrl() on the default
121 // contextual suggestion URL.
Gheorghe Comanicif7c65862017-09-07 18:40:29122 GURL ExperimentalContextualSuggestionsUrl(
Daniel Kenji Toyamaf1e4b572017-08-03 16:31:11123 const std::string& current_url,
124 const TemplateURLService* template_url_service) const;
125
Gheorghe Comanici923739272017-09-22 20:32:14126 // Upon succesful creation of an HTTP GET request for default contextual
Gheorghe Comanicif7c65862017-09-07 18:40:29127 // suggestions, the |callback| function is run with the HTTP GET request as a
128 // parameter.
129 //
130 // This function is called by CreateContextualSuggestionsRequest. See its
131 // function definition for details on the parameters.
132 void CreateDefaultRequest(const std::string& current_url,
Jenny Zhang5bc2e3d2018-09-10 18:50:55133 const AutocompleteInput& input,
Gheorghe Comanicif7c65862017-09-07 18:40:29134 const TemplateURLService* template_url_service,
Maks Orlovich1b208512018-06-13 21:08:17135 StartCallback start_callback,
136 CompletionCallback completion_callback);
Gheorghe Comanicif7c65862017-09-07 18:40:29137
Gheorghe Comanici923739272017-09-22 20:32:14138 // Upon succesful creation of an HTTP POST request for experimental contextual
Gheorghe Comanicif7c65862017-09-07 18:40:29139 // suggestions, the |callback| function is run with the HTTP POST request as a
140 // parameter.
141 //
142 // This function is called by CreateContextualSuggestionsRequest. See its
143 // function definition for details on the parameters.
144 void CreateExperimentalRequest(const std::string& current_url,
Gheorghe Comanici034cff62018-01-27 03:34:00145 const base::Time& visit_time,
Gheorghe Comanicif7c65862017-09-07 18:40:29146 const GURL& suggest_url,
Maks Orlovich1b208512018-06-13 21:08:17147 StartCallback start_callback,
148 CompletionCallback completion_callback);
Daniel Kenji Toyamaf1e4b572017-08-03 16:31:11149
Maks Orlovich1b208512018-06-13 21:08:17150 // Tries to load the suggestions from network, using the token when available.
151 //
152 // |request| is expected to be the request for suggestions filled in with
Maks Orlovich5e2e8492018-06-26 20:04:04153 // everything but maybe the authentication token and the request body.
154 //
155 // |request_body|, if not empty, will be attached as the upload body to
156 // the request.
Maks Orlovich1b208512018-06-13 21:08:17157 //
158 // |traffic_annotation| is the appropriate annotations for making the network
159 // request to load the suggestions.
160 //
161 // |start_callback|, |completion_callback| are the same as passed to
162 // CreateContextualSuggestionsRequest()
163 //
164 // |error| and |access_token| are the results of token request.
165 void AccessTokenAvailable(std::unique_ptr<network::ResourceRequest> request,
Maks Orlovich5e2e8492018-06-26 20:04:04166 std::string request_body,
Maks Orlovich1b208512018-06-13 21:08:17167 net::NetworkTrafficAnnotationTag traffic_annotation,
168 StartCallback start_callback,
169 CompletionCallback completion_callback,
Colin Blundella29afeac2018-06-12 14:05:47170 GoogleServiceAuthError error,
Colin Blundell80bede82018-07-16 11:18:27171 identity::AccessTokenInfo access_token_info);
Daniel Kenji Toyamaf1e4b572017-08-03 16:31:11172
Maks Orlovich1b208512018-06-13 21:08:17173 // Activates a loader for |request|, wiring it up to |completion_callback|,
Maks Orlovich5e2e8492018-06-26 20:04:04174 // and calls |start_callback|. If |request_body| isn't empty, it will be
175 // attached as upload bytes.
Maks Orlovich1b208512018-06-13 21:08:17176 void StartDownloadAndTransferLoader(
177 std::unique_ptr<network::ResourceRequest> request,
Maks Orlovich5e2e8492018-06-26 20:04:04178 std::string request_body,
Maks Orlovich1b208512018-06-13 21:08:17179 net::NetworkTrafficAnnotationTag traffic_annotation,
180 StartCallback start_callback,
181 CompletionCallback completion_callback);
182
183 scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_;
Jochen Eisinger4f96a312018-06-11 15:41:26184 identity::IdentityManager* identity_manager_;
Daniel Kenji Toyamaf1e4b572017-08-03 16:31:11185
186 // Helper for fetching OAuth2 access tokens. This is non-null when an access
187 // token request is currently in progress.
Colin Blundell0ee42ed62017-12-20 14:11:29188 std::unique_ptr<identity::PrimaryAccountAccessTokenFetcher> token_fetcher_;
Daniel Kenji Toyamaf1e4b572017-08-03 16:31:11189
190 DISALLOW_COPY_AND_ASSIGN(ContextualSuggestionsService);
191};
192
193#endif // COMPONENTS_OMNIBOX_BROWSER_CONTEXTUAL_SUGGESTIONS_SERVICE_H_