blob: 3a6390f59eebf0c51e33cbfe712313d41eac5658 [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"
Maks Orlovich1b208512018-06-13 21:08:1713#include "net/traffic_annotation/network_traffic_annotation.h"
Daniel Kenji Toyamaf1e4b572017-08-03 16:31:1114#include "url/gurl.h"
15
Jochen Eisinger4f96a312018-06-11 15:41:2616namespace base {
17class Time;
18}
19namespace identity {
20class IdentityManager;
21class PrimaryAccountAccessTokenFetcher;
22} // namespace identity
Jochen Eisinger4f96a312018-06-11 15:41:2623class GoogleServiceAuthError;
Daniel Kenji Toyamaf1e4b572017-08-03 16:31:1124class TemplateURLService;
25
Maks Orlovich1b208512018-06-13 21:08:1726namespace network {
27struct ResourceRequest;
28class SharedURLLoaderFactory;
29class SimpleURLLoader;
30} // namespace network
31
Daniel Kenji Toyamaf1e4b572017-08-03 16:31:1132// A service to fetch suggestions from a remote endpoint given a URL.
33class ContextualSuggestionsService : public KeyedService {
34 public:
Jochen Eisinger4f96a312018-06-11 15:41:2635 // |identity_manager| may be null but only unauthenticated requests will
36 // issued.
Maks Orlovich1b208512018-06-13 21:08:1737 ContextualSuggestionsService(
38 identity::IdentityManager* identity_manager,
39 scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory);
Daniel Kenji Toyamaf1e4b572017-08-03 16:31:1140
41 ~ContextualSuggestionsService() override;
42
Maks Orlovich1b208512018-06-13 21:08:1743 using StartCallback = base::OnceCallback<void(
44 std::unique_ptr<network::SimpleURLLoader> loader)>;
Daniel Kenji Toyamaf1e4b572017-08-03 16:31:1145
Maks Orlovich1b208512018-06-13 21:08:1746 using CompletionCallback =
47 base::OnceCallback<void(const network::SimpleURLLoader* source,
48 std::unique_ptr<std::string> response_body)>;
49
50 // Creates a loader for contextual suggestions for |current_url| and passes
51 // the loader to |start_callback|. It uses a number of signals to create the
52 // loader, including field trial / experimental parameters, and it may
53 // pass a nullptr to |start_callback| (see below for details).
Daniel Kenji Toyamaf1e4b572017-08-03 16:31:1154 //
55 // |current_url| may be empty, in which case the system will never use the
56 // experimental suggestions service. It's possible the non-experimental
57 // service may decide to offer general-purpose suggestions.
58 //
Gheorghe Comanici034cff62018-01-27 03:34:0059 // |visit_time| is the time of the visit for the URL for which suggestions
60 // should be fetched.
61 //
Daniel Kenji Toyamaf1e4b572017-08-03 16:31:1162 // |template_url_service| may be null, but some services may be disabled.
63 //
Maks Orlovich1b208512018-06-13 21:08:1764 // |start_callback| is called to transfer ownership of the created loader to
65 // whatever function/class receives the callback.
66 // |start_callback| is called with a nullptr argument if:
Daniel Kenji Toyamaf1e4b572017-08-03 16:31:1167 // * The service is waiting for a previously-requested authentication token.
68 // * The authentication token had any issues.
69 //
Maks Orlovich1b208512018-06-13 21:08:1770 // |completion_callback| will be invoked when the transfer is done.
71 //
Daniel Kenji Toyamaf1e4b572017-08-03 16:31:1172 // This method sends a request for an OAuth2 token and temporarily
73 // instantiates |token_fetcher_|.
74 void CreateContextualSuggestionsRequest(
75 const std::string& current_url,
Gheorghe Comanici034cff62018-01-27 03:34:0076 const base::Time& visit_time,
Daniel Kenji Toyamaf1e4b572017-08-03 16:31:1177 const TemplateURLService* template_url_service,
Maks Orlovich1b208512018-06-13 21:08:1778 StartCallback start_callback,
79 CompletionCallback completion_callback);
Daniel Kenji Toyamaf1e4b572017-08-03 16:31:1180
Gheorghe Comanici86bbdf62017-08-28 17:20:3381 // Advises the service to stop any process that creates a suggestion request.
82 void StopCreatingContextualSuggestionsRequest();
83
Daniel Kenji Toyamaf1e4b572017-08-03 16:31:1184 // Returns a URL representing the address of the server where the zero suggest
85 // request is being sent. Does not take into account whether sending this
86 // request is prohibited (e.g. in an incognito window).
87 // Returns an invalid URL (i.e.: GURL::is_valid() == false) in case of an
88 // error.
89 //
90 // |current_url| is the page the user is currently browsing and may be empty.
91 //
92 // Note that this method is public and is also used by ZeroSuggestProvider for
93 // suggestions that do not take |current_url| into consideration.
94 static GURL ContextualSuggestionsUrl(
95 const std::string& current_url,
96 const TemplateURLService* template_url_service);
97
98 private:
99 // Returns a URL representing the address of the server where the zero suggest
100 // requests are being redirected when serving experimental suggestions.
101 //
102 // Returns a valid URL only if all the folowing conditions are true:
103 // * The |current_url| is non-empty.
104 // * The |default_provider| is Google.
105 // * The user is in the ZeroSuggestRedirectToChrome field trial.
106 // * The field trial provides a valid server address where the suggest request
107 // is redirected.
108 // * The suggest request is over HTTPS. This avoids leaking the current page
109 // URL or personal data in unencrypted network traffic.
110 // Note: these checks are in addition to CanSendUrl() on the default
111 // contextual suggestion URL.
Gheorghe Comanicif7c65862017-09-07 18:40:29112 GURL ExperimentalContextualSuggestionsUrl(
Daniel Kenji Toyamaf1e4b572017-08-03 16:31:11113 const std::string& current_url,
114 const TemplateURLService* template_url_service) const;
115
Gheorghe Comanici923739272017-09-22 20:32:14116 // Upon succesful creation of an HTTP GET request for default contextual
Gheorghe Comanicif7c65862017-09-07 18:40:29117 // suggestions, the |callback| function is run with the HTTP GET request as a
118 // parameter.
119 //
120 // This function is called by CreateContextualSuggestionsRequest. See its
121 // function definition for details on the parameters.
122 void CreateDefaultRequest(const std::string& current_url,
123 const TemplateURLService* template_url_service,
Maks Orlovich1b208512018-06-13 21:08:17124 StartCallback start_callback,
125 CompletionCallback completion_callback);
Gheorghe Comanicif7c65862017-09-07 18:40:29126
Gheorghe Comanici923739272017-09-22 20:32:14127 // Upon succesful creation of an HTTP POST request for experimental contextual
Gheorghe Comanicif7c65862017-09-07 18:40:29128 // suggestions, the |callback| function is run with the HTTP POST request as a
129 // parameter.
130 //
131 // This function is called by CreateContextualSuggestionsRequest. See its
132 // function definition for details on the parameters.
133 void CreateExperimentalRequest(const std::string& current_url,
Gheorghe Comanici034cff62018-01-27 03:34:00134 const base::Time& visit_time,
Gheorghe Comanicif7c65862017-09-07 18:40:29135 const GURL& suggest_url,
Maks Orlovich1b208512018-06-13 21:08:17136 StartCallback start_callback,
137 CompletionCallback completion_callback);
Daniel Kenji Toyamaf1e4b572017-08-03 16:31:11138
Maks Orlovich1b208512018-06-13 21:08:17139 // Tries to load the suggestions from network, using the token when available.
140 //
141 // |request| is expected to be the request for suggestions filled in with
142 // everything but maybe the authentication token.
143 //
144 // |traffic_annotation| is the appropriate annotations for making the network
145 // request to load the suggestions.
146 //
147 // |start_callback|, |completion_callback| are the same as passed to
148 // CreateContextualSuggestionsRequest()
149 //
150 // |error| and |access_token| are the results of token request.
151 void AccessTokenAvailable(std::unique_ptr<network::ResourceRequest> request,
152 net::NetworkTrafficAnnotationTag traffic_annotation,
153 StartCallback start_callback,
154 CompletionCallback completion_callback,
Colin Blundella29afeac2018-06-12 14:05:47155 GoogleServiceAuthError error,
156 std::string access_token);
Daniel Kenji Toyamaf1e4b572017-08-03 16:31:11157
Maks Orlovich1b208512018-06-13 21:08:17158 // Activates a loader for |request|, wiring it up to |completion_callback|,
159 // and calls |start_callback|.
160 void StartDownloadAndTransferLoader(
161 std::unique_ptr<network::ResourceRequest> request,
162 net::NetworkTrafficAnnotationTag traffic_annotation,
163 StartCallback start_callback,
164 CompletionCallback completion_callback);
165
166 scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_;
Jochen Eisinger4f96a312018-06-11 15:41:26167 identity::IdentityManager* identity_manager_;
Daniel Kenji Toyamaf1e4b572017-08-03 16:31:11168
169 // Helper for fetching OAuth2 access tokens. This is non-null when an access
170 // token request is currently in progress.
Colin Blundell0ee42ed62017-12-20 14:11:29171 std::unique_ptr<identity::PrimaryAccountAccessTokenFetcher> token_fetcher_;
Daniel Kenji Toyamaf1e4b572017-08-03 16:31:11172
173 DISALLOW_COPY_AND_ASSIGN(ContextualSuggestionsService);
174};
175
176#endif // COMPONENTS_OMNIBOX_BROWSER_CONTEXTUAL_SUGGESTIONS_SERVICE_H_