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. 4 5 #ifndef CHROME_BROWSER_SEARCH_SUGGESTIONS_SUGGESTIONS_SERVICE_H_ 6 #define CHROME_BROWSER_SEARCH_SUGGESTIONS_SUGGESTIONS_SERVICE_H_ 7 8 #include <string> 9 #include <vector> 10 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/time/time.h" 18 #include "chrome/browser/search/suggestions/proto/suggestions.pb.h" 19 #include "chrome/browser/search/suggestions/thumbnail_manager.h" 20 #include "components/keyed_service/core/keyed_service.h" 21 #include "net/url_request/url_fetcher_delegate.h" 22 #include "ui/gfx/image/image_skia.h" 23 #include "url/gurl.h" 24 25 class Profile; 26 27 namespace user_prefs { 28 class PrefRegistrySyncable; 29 } // namespace user_prefs 30 31 namespace suggestions { 32 33 class SuggestionsStore; 34 35 extern const char kSuggestionsFieldTrialName[]; 36 extern const char kSuggestionsFieldTrialURLParam[]; 37 extern const char kSuggestionsFieldTrialSuggestionsSuffixParam[]; 38 extern const char kSuggestionsFieldTrialBlacklistSuffixParam[]; 39 extern const char kSuggestionsFieldTrialStateParam[]; 40 extern const char kSuggestionsFieldTrialControlParam[]; 41 extern const char kSuggestionsFieldTrialStateEnabled[]; 42 43 // An interface to fetch server suggestions asynchronously. 44 class SuggestionsService : public KeyedService, public net::URLFetcherDelegate { 45 public: 46 typedef base::Callback<void(const SuggestionsProfile&)> ResponseCallback; 47 48 SuggestionsService(Profile* profile, 49 scoped_ptr<SuggestionsStore> suggestions_store); 50 virtual ~SuggestionsService(); 51 52 // Whether this service is enabled. 53 static bool IsEnabled(); 54 55 // Whether the user is part of a control group. 56 static bool IsControlGroup(); 57 58 // Request suggestions data, which will be passed to |callback|. Initiates a 59 // fetch request unless a pending one exists. To prevent multiple requests, 60 // we place all |callback|s in a queue and update them simultaneously when 61 // fetch request completes. Also posts a task to execute OnRequestTimeout 62 // if the request hasn't completed in a given amount of time. 63 void FetchSuggestionsData(ResponseCallback callback); 64 65 // Similar to FetchSuggestionsData but doesn't post a task to execute 66 // OnDelaySinceFetch. 67 void FetchSuggestionsDataNoTimeout(ResponseCallback callback); 68 69 // Retrieves stored thumbnail for website |url| asynchronously. Calls 70 // |callback| with Bitmap pointer if found, and NULL otherwise. 71 void GetPageThumbnail( 72 const GURL& url, 73 base::Callback<void(const GURL&, const SkBitmap*)> callback); 74 75 // Issue a blacklist request. If there is already a blacklist request 76 // in flight, the new blacklist request is ignored. 77 void BlacklistURL(const GURL& candidate_url, ResponseCallback callback); 78 79 // Register SuggestionsService related prefs in the Profile prefs. 80 static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry); 81 82 private: 83 FRIEND_TEST_ALL_PREFIXES(SuggestionsServiceTest, FetchSuggestionsData); 84 85 // Called to service the requestors if the issued suggestions request has 86 // not completed in a given amount of time. 87 virtual void OnRequestTimeout(); 88 89 // net::URLFetcherDelegate implementation. 90 // Called when fetch request completes. Parses the received suggestions data, 91 // and dispatches them to callbacks stored in queue. 92 virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE; 93 94 // KeyedService implementation. 95 virtual void Shutdown() OVERRIDE; 96 97 // Determines whether |request| is a blacklisting request. 98 bool IsBlacklistRequest(net::URLFetcher* request) const; 99 100 // Creates a request to the suggestions service, properly setting headers. 101 net::URLFetcher* CreateSuggestionsRequest(const GURL& url); 102 103 // Load the cached suggestions and service the requestors with them. 104 void ServeFromCache(); 105 106 // The cache for the suggestions. 107 scoped_ptr<SuggestionsStore> suggestions_store_; 108 109 // Contains the current suggestions fetch request. Will only have a value 110 // while a request is pending, and will be reset by |OnURLFetchComplete|. 111 scoped_ptr<net::URLFetcher> pending_request_; 112 113 // A closure that is run on a timeout from issuing the suggestions fetch 114 // request, if the request hasn't completed. 115 scoped_ptr<base::CancelableClosure> pending_timeout_closure_; 116 117 // The start time of the previous suggestions request. This is used to measure 118 // the latency of requests. Initially zero. 119 base::TimeTicks last_request_started_time_; 120 121 // The URL to fetch suggestions data from. 122 GURL suggestions_url_; 123 124 // Prefix for building the blacklisting URL. 125 std::string blacklist_url_prefix_; 126 127 // Queue of callbacks. These are flushed when fetch request completes. 128 std::vector<ResponseCallback> waiting_requestors_; 129 130 // Used to obtain server thumbnails, if available. 131 scoped_ptr<ThumbnailManager> thumbnail_manager_; 132 133 Profile* profile_; 134 135 // For callbacks may be run after destruction. 136 base::WeakPtrFactory<SuggestionsService> weak_ptr_factory_; 137 138 // Timeout (in ms) before serving requestors after a fetch suggestions request 139 // has been issued. 140 int request_timeout_ms_; 141 142 DISALLOW_COPY_AND_ASSIGN(SuggestionsService); 143 }; 144 145 } // namespace suggestions 146 147 #endif // CHROME_BROWSER_SEARCH_SUGGESTIONS_SUGGESTIONS_SERVICE_H_ 148