1 // Copyright 2014 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.
5 #ifndef COMPONENTS_SUGGESTIONS_SUGGESTIONS_SERVICE_H_
6 #define COMPONENTS_SUGGESTIONS_SUGGESTIONS_SERVICE_H_
11 #include "base/basictypes.h"
12 #include "base/callback.h"
13 #include "base/cancelable_callback.h"
14 #include "base/gtest_prod_util.h"
15 #include "base/memory/scoped_ptr.h"
16 #include "base/memory/weak_ptr.h"
17 #include "base/threading/thread_checker.h"
18 #include "base/time/time.h"
19 #include "components/keyed_service/core/keyed_service.h"
20 #include "components/suggestions/image_manager.h"
21 #include "components/suggestions/proto/suggestions.pb.h"
22 #include "net/url_request/url_fetcher_delegate.h"
23 #include "ui/gfx/image/image_skia.h"
27 class URLRequestContextGetter;
30 namespace user_prefs {
31 class PrefRegistrySyncable;
32 } // namespace user_prefs
34 namespace suggestions {
37 class SuggestionsStore;
39 extern const char kSuggestionsFieldTrialName[];
40 extern const char kSuggestionsFieldTrialURLParam[];
41 extern const char kSuggestionsFieldTrialCommonParamsParam[];
42 extern const char kSuggestionsFieldTrialBlacklistPathParam[];
43 extern const char kSuggestionsFieldTrialBlacklistUrlParam[];
44 extern const char kSuggestionsFieldTrialStateParam[];
45 extern const char kSuggestionsFieldTrialControlParam[];
46 extern const char kSuggestionsFieldTrialStateEnabled[];
47 extern const int64 kDefaultExpiryUsec;
49 // An interface to fetch server suggestions asynchronously.
50 class SuggestionsService : public KeyedService, public net::URLFetcherDelegate {
52 typedef base::Callback<void(const SuggestionsProfile&)> ResponseCallback;
55 net::URLRequestContextGetter* url_request_context,
56 scoped_ptr<SuggestionsStore> suggestions_store,
57 scoped_ptr<ImageManager> thumbnail_manager,
58 scoped_ptr<BlacklistStore> blacklist_store);
59 virtual ~SuggestionsService();
61 // Whether this service is enabled.
62 static bool IsEnabled();
64 // Whether the user is part of a control group.
65 static bool IsControlGroup();
67 // Request suggestions data, which will be passed to |callback|. Initiates a
68 // fetch request unless a pending one exists. To prevent multiple requests,
69 // we place all |callback|s in a queue and update them simultaneously when
70 // fetch request completes. Also posts a task to execute OnRequestTimeout
71 // if the request hasn't completed in a given amount of time.
72 void FetchSuggestionsData(ResponseCallback callback);
74 // Similar to FetchSuggestionsData but doesn't post a task to execute
76 void FetchSuggestionsDataNoTimeout(ResponseCallback callback);
78 // Retrieves stored thumbnail for website |url| asynchronously. Calls
79 // |callback| with Bitmap pointer if found, and NULL otherwise.
80 void GetPageThumbnail(
82 base::Callback<void(const GURL&, const SkBitmap*)> callback);
84 // Issue a blacklist request. If there is already a blacklist request
85 // in flight, the new blacklist request is ignored.
86 void BlacklistURL(const GURL& candidate_url,
87 const ResponseCallback& callback);
89 // Determines which URL a blacklist request was for, irrespective of the
90 // request's status. Returns false if |request| is not a blacklist request.
91 static bool GetBlacklistedUrl(const net::URLFetcher& request, GURL* url);
93 // Register SuggestionsService related prefs in the Profile prefs.
94 static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
96 // Sets default timestamp for suggestions which do not have expiry timestamp.
97 void SetDefaultExpiryTimestamp(SuggestionsProfile* suggestions,
98 int64 timestamp_usec);
100 FRIEND_TEST_ALL_PREFIXES(SuggestionsServiceTest, BlacklistURLFails);
101 FRIEND_TEST_ALL_PREFIXES(SuggestionsServiceTest, FetchSuggestionsData);
102 FRIEND_TEST_ALL_PREFIXES(SuggestionsServiceTest, UpdateBlacklistDelay);
105 void IssueRequest(const GURL& url);
107 // Creates a request to the suggestions service, properly setting headers.
108 net::URLFetcher* CreateSuggestionsRequest(const GURL& url);
110 // Called to service the requestors if the issued suggestions request has
111 // not completed in a given amount of time.
112 virtual void OnRequestTimeout();
114 // net::URLFetcherDelegate implementation.
115 // Called when fetch request completes. Parses the received suggestions data,
116 // and dispatches them to callbacks stored in queue.
117 virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE;
119 // KeyedService implementation.
120 virtual void Shutdown() OVERRIDE;
122 // Load the cached suggestions and service the requestors with them.
123 void ServeFromCache();
125 // Apply the local blacklist to |suggestions|, then serve the requestors.
126 void FilterAndServe(SuggestionsProfile* suggestions);
128 // Schedule a blacklisting request if the local blacklist isn't empty.
129 // |last_request_successful| is used for exponentially backing off when
131 void ScheduleBlacklistUpload(bool last_request_successful);
133 // If the local blacklist isn't empty, pick a URL from it and issue a
134 // blacklist request for it.
135 void UploadOneFromBlacklist();
137 // Updates |blacklist_delay_sec_| based on the success of the last request.
138 void UpdateBlacklistDelay(bool last_request_successful);
141 int blacklist_delay() const { return blacklist_delay_sec_; }
142 void set_blacklist_delay(int delay) { blacklist_delay_sec_ = delay; }
144 base::ThreadChecker thread_checker_;
146 // The cache for the suggestions.
147 scoped_ptr<SuggestionsStore> suggestions_store_;
149 // The local cache for temporary blacklist, until uploaded to the server.
150 scoped_ptr<BlacklistStore> blacklist_store_;
152 // Contains the current suggestions fetch request. Will only have a value
153 // while a request is pending, and will be reset by |OnURLFetchComplete|.
154 scoped_ptr<net::URLFetcher> pending_request_;
156 // A closure that is run on a timeout from issuing the suggestions fetch
157 // request, if the request hasn't completed.
158 scoped_ptr<base::CancelableClosure> pending_timeout_closure_;
160 // The start time of the previous suggestions request. This is used to measure
161 // the latency of requests. Initially zero.
162 base::TimeTicks last_request_started_time_;
164 // The URL to fetch suggestions data from.
165 GURL suggestions_url_;
167 // Prefix for building the blacklisting URL.
168 std::string blacklist_url_prefix_;
170 // Queue of callbacks. These are flushed when fetch request completes.
171 std::vector<ResponseCallback> waiting_requestors_;
173 // Used to obtain server thumbnails, if available.
174 scoped_ptr<ImageManager> thumbnail_manager_;
176 net::URLRequestContextGetter* url_request_context_;
178 // Delay used when scheduling a blacklisting task.
179 int blacklist_delay_sec_;
181 // For callbacks may be run after destruction.
182 base::WeakPtrFactory<SuggestionsService> weak_ptr_factory_;
184 // Timeout (in ms) before serving requestors after a fetch suggestions request
186 int request_timeout_ms_;
188 DISALLOW_COPY_AND_ASSIGN(SuggestionsService);
191 } // namespace suggestions
193 #endif // COMPONENTS_SUGGESTIONS_SUGGESTIONS_SERVICE_H_