| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef COMPONENTS_SUGGESTIONS_SUGGESTIONS_SERVICE_H_ | 5 #ifndef COMPONENTS_SUGGESTIONS_SUGGESTIONS_SERVICE_H_ |
| 6 #define COMPONENTS_SUGGESTIONS_SUGGESTIONS_SERVICE_H_ | 6 #define COMPONENTS_SUGGESTIONS_SUGGESTIONS_SERVICE_H_ |
| 7 | 7 |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include <string> | 10 #include <string> |
| 11 | 11 |
| 12 #include "base/callback.h" | 12 #include "base/callback.h" |
| 13 #include "base/callback_list.h" |
| 13 #include "base/gtest_prod_util.h" | 14 #include "base/gtest_prod_util.h" |
| 14 #include "base/macros.h" | 15 #include "base/macros.h" |
| 15 #include "base/memory/scoped_ptr.h" | 16 #include "base/memory/scoped_ptr.h" |
| 16 #include "base/memory/weak_ptr.h" | 17 #include "base/memory/weak_ptr.h" |
| 18 #include "base/scoped_observer.h" |
| 17 #include "base/threading/thread_checker.h" | 19 #include "base/threading/thread_checker.h" |
| 18 #include "base/time/time.h" | 20 #include "base/time/time.h" |
| 19 #include "components/keyed_service/core/keyed_service.h" | 21 #include "components/keyed_service/core/keyed_service.h" |
| 20 #include "components/suggestions/proto/suggestions.pb.h" | 22 #include "components/suggestions/proto/suggestions.pb.h" |
| 21 #include "components/suggestions/suggestions_utils.h" | 23 #include "components/sync_driver/sync_service_observer.h" |
| 22 #include "net/url_request/url_fetcher_delegate.h" | 24 #include "net/url_request/url_fetcher_delegate.h" |
| 23 #include "url/gurl.h" | 25 #include "url/gurl.h" |
| 24 | 26 |
| 25 namespace net { | 27 namespace net { |
| 26 class URLRequestContextGetter; | 28 class URLRequestContextGetter; |
| 27 } // namespace net | 29 } // namespace net |
| 28 | 30 |
| 31 namespace sync_driver { |
| 32 class SyncService; |
| 33 } |
| 34 |
| 29 namespace user_prefs { | 35 namespace user_prefs { |
| 30 class PrefRegistrySyncable; | 36 class PrefRegistrySyncable; |
| 31 } // namespace user_prefs | 37 } // namespace user_prefs |
| 32 | 38 |
| 33 class OAuth2TokenService; | 39 class OAuth2TokenService; |
| 34 class SigninManagerBase; | 40 class SigninManagerBase; |
| 35 class SkBitmap; | 41 class SkBitmap; |
| 36 | 42 |
| 37 namespace suggestions { | 43 namespace suggestions { |
| 38 | 44 |
| 39 class BlacklistStore; | 45 class BlacklistStore; |
| 40 class ImageManager; | 46 class ImageManager; |
| 41 class SuggestionsStore; | 47 class SuggestionsStore; |
| 42 | 48 |
| 43 // An interface to fetch server suggestions asynchronously. | 49 // An interface to fetch server suggestions asynchronously. |
| 44 class SuggestionsService : public KeyedService, public net::URLFetcherDelegate { | 50 class SuggestionsService : public KeyedService, |
| 51 public net::URLFetcherDelegate, |
| 52 public sync_driver::SyncServiceObserver { |
| 45 public: | 53 public: |
| 46 using ResponseCallback = base::Callback<void(const SuggestionsProfile&)>; | 54 using ResponseCallback = base::Callback<void(const SuggestionsProfile&)>; |
| 47 using BitmapCallback = base::Callback<void(const GURL&, const SkBitmap*)>; | 55 using BitmapCallback = base::Callback<void(const GURL&, const SkBitmap*)>; |
| 48 | 56 |
| 49 SuggestionsService( | 57 using ResponseCallbackList = |
| 50 const SigninManagerBase* signin_manager, | 58 base::CallbackList<void(const SuggestionsProfile&)>; |
| 51 OAuth2TokenService* token_service, | 59 |
| 52 net::URLRequestContextGetter* url_request_context, | 60 SuggestionsService(const SigninManagerBase* signin_manager, |
| 53 scoped_ptr<SuggestionsStore> suggestions_store, | 61 OAuth2TokenService* token_service, |
| 54 scoped_ptr<ImageManager> thumbnail_manager, | 62 sync_driver::SyncService* sync_service, |
| 55 scoped_ptr<BlacklistStore> blacklist_store); | 63 net::URLRequestContextGetter* url_request_context, |
| 64 scoped_ptr<SuggestionsStore> suggestions_store, |
| 65 scoped_ptr<ImageManager> thumbnail_manager, |
| 66 scoped_ptr<BlacklistStore> blacklist_store); |
| 56 ~SuggestionsService() override; | 67 ~SuggestionsService() override; |
| 57 | 68 |
| 58 // Requests suggestions data. Passes the currently cached data to |callback|. | 69 // Initiates a network request for suggestions if sync state allows and there |
| 59 // |sync_state| influences the behavior of this function (see SyncState | 70 // is no pending request. Returns true iff sync state allowed for a request, |
| 60 // definition). | 71 // whether a new request was actually sent or not. |
| 61 // | 72 bool FetchSuggestionsData(); |
| 62 // |sync_state| must be specified based on the current state of the system | 73 |
| 63 // (see suggestions::GetSyncState). Callers should call this function again if | 74 // Returns the current set of suggestions from the cache. |
| 64 // sync state changes. | 75 SuggestionsProfile GetSuggestionsDataFromCache() const; |
| 65 // | 76 |
| 66 // If state allows for a network request, it is initiated unless a pending one | 77 // Adds a callback that is called when the suggestions are updated. |
| 67 // exists, to fill the cache for next time. | 78 scoped_ptr<ResponseCallbackList::Subscription> AddCallback( |
| 68 void FetchSuggestionsData(SyncState sync_state, | 79 const ResponseCallback& callback) WARN_UNUSED_RESULT; |
| 69 const ResponseCallback& callback); | |
| 70 | 80 |
| 71 // Retrieves stored thumbnail for website |url| asynchronously. Calls | 81 // Retrieves stored thumbnail for website |url| asynchronously. Calls |
| 72 // |callback| with Bitmap pointer if found, and NULL otherwise. | 82 // |callback| with Bitmap pointer if found, and NULL otherwise. |
| 73 void GetPageThumbnail(const GURL& url, const BitmapCallback& callback); | 83 void GetPageThumbnail(const GURL& url, const BitmapCallback& callback); |
| 74 | 84 |
| 75 // A version of |GetPageThumbnail| that explicitly supplies the download URL | 85 // A version of |GetPageThumbnail| that explicitly supplies the download URL |
| 76 // for the thumbnail. Replaces any pre-existing thumbnail URL with the | 86 // for the thumbnail. Replaces any pre-existing thumbnail URL with the |
| 77 // supplied one. | 87 // supplied one. |
| 78 void GetPageThumbnailWithURL(const GURL& url, | 88 void GetPageThumbnailWithURL(const GURL& url, |
| 79 const GURL& thumbnail_url, | 89 const GURL& thumbnail_url, |
| 80 const BitmapCallback& callback); | 90 const BitmapCallback& callback); |
| 81 | 91 |
| 82 // Adds a URL to the blacklist cache, invoking |callback| on success or | 92 // Adds a URL to the blacklist cache, returning true on success or false on |
| 83 // |fail_callback| otherwise. The URL will eventually be uploaded to the | 93 // failure. The URL will eventually be uploaded to the server. |
| 84 // server. | 94 bool BlacklistURL(const GURL& candidate_url); |
| 85 void BlacklistURL(const GURL& candidate_url, | |
| 86 const ResponseCallback& callback, | |
| 87 const base::Closure& fail_callback); | |
| 88 | 95 |
| 89 // Removes a URL from the local blacklist, then invokes |callback|. If the URL | 96 // Removes a URL from the local blacklist, returning true on success or false |
| 90 // cannot be removed, the |fail_callback| is called. | 97 // on failure. |
| 91 void UndoBlacklistURL(const GURL& url, | 98 bool UndoBlacklistURL(const GURL& url); |
| 92 const ResponseCallback& callback, | |
| 93 const base::Closure& fail_callback); | |
| 94 | 99 |
| 95 // Removes all URLs from the blacklist then invokes |callback|. | 100 // Removes all URLs from the blacklist. |
| 96 void ClearBlacklist(const ResponseCallback& callback); | 101 void ClearBlacklist(); |
| 97 | 102 |
| 98 // Determines which URL a blacklist request was for, irrespective of the | 103 // Determines which URL a blacklist request was for, irrespective of the |
| 99 // request's status. Returns false if |request| is not a blacklist request. | 104 // request's status. Returns false if |request| is not a blacklist request. |
| 100 static bool GetBlacklistedUrl(const net::URLFetcher& request, GURL* url); | 105 static bool GetBlacklistedUrl(const net::URLFetcher& request, GURL* url); |
| 101 | 106 |
| 102 // Register SuggestionsService related prefs in the Profile prefs. | 107 // Register SuggestionsService related prefs in the Profile prefs. |
| 103 static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry); | 108 static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry); |
| 104 | 109 |
| 105 private: | 110 private: |
| 106 friend class SuggestionsServiceTest; | 111 friend class SuggestionsServiceTest; |
| 112 FRIEND_TEST_ALL_PREFIXES(SuggestionsServiceTest, FetchSuggestionsData); |
| 113 FRIEND_TEST_ALL_PREFIXES(SuggestionsServiceTest, |
| 114 FetchSuggestionsDataSyncDisabled); |
| 107 FRIEND_TEST_ALL_PREFIXES(SuggestionsServiceTest, | 115 FRIEND_TEST_ALL_PREFIXES(SuggestionsServiceTest, |
| 108 FetchSuggestionsDataNoAccessToken); | 116 FetchSuggestionsDataNoAccessToken); |
| 109 FRIEND_TEST_ALL_PREFIXES(SuggestionsServiceTest, | 117 FRIEND_TEST_ALL_PREFIXES(SuggestionsServiceTest, |
| 110 IssueRequestIfNoneOngoingError); | 118 IssueRequestIfNoneOngoingError); |
| 111 FRIEND_TEST_ALL_PREFIXES(SuggestionsServiceTest, | 119 FRIEND_TEST_ALL_PREFIXES(SuggestionsServiceTest, |
| 112 IssueRequestIfNoneOngoingResponseNotOK); | 120 IssueRequestIfNoneOngoingResponseNotOK); |
| 113 FRIEND_TEST_ALL_PREFIXES(SuggestionsServiceTest, BlacklistURL); | 121 FRIEND_TEST_ALL_PREFIXES(SuggestionsServiceTest, BlacklistURL); |
| 114 FRIEND_TEST_ALL_PREFIXES(SuggestionsServiceTest, BlacklistURLRequestFails); | 122 FRIEND_TEST_ALL_PREFIXES(SuggestionsServiceTest, BlacklistURLRequestFails); |
| 115 FRIEND_TEST_ALL_PREFIXES(SuggestionsServiceTest, ClearBlacklist); | 123 FRIEND_TEST_ALL_PREFIXES(SuggestionsServiceTest, ClearBlacklist); |
| 116 FRIEND_TEST_ALL_PREFIXES(SuggestionsServiceTest, UndoBlacklistURL); | 124 FRIEND_TEST_ALL_PREFIXES(SuggestionsServiceTest, UndoBlacklistURL); |
| 117 FRIEND_TEST_ALL_PREFIXES(SuggestionsServiceTest, UndoBlacklistURLFailsHelper); | 125 FRIEND_TEST_ALL_PREFIXES(SuggestionsServiceTest, UndoBlacklistURLFailsHelper); |
| 118 FRIEND_TEST_ALL_PREFIXES(SuggestionsServiceTest, GetBlacklistedUrl); | 126 FRIEND_TEST_ALL_PREFIXES(SuggestionsServiceTest, GetBlacklistedUrl); |
| 119 FRIEND_TEST_ALL_PREFIXES(SuggestionsServiceTest, UpdateBlacklistDelay); | 127 FRIEND_TEST_ALL_PREFIXES(SuggestionsServiceTest, UpdateBlacklistDelay); |
| 120 FRIEND_TEST_ALL_PREFIXES(SuggestionsServiceTest, CheckDefaultTimeStamps); | 128 FRIEND_TEST_ALL_PREFIXES(SuggestionsServiceTest, CheckDefaultTimeStamps); |
| 121 | 129 |
| 122 // Returns whether OAuth2 authentication is enabled. If false, cookies are | 130 // Returns whether OAuth2 authentication is enabled. If false, cookies are |
| 123 // used for authentication. | 131 // used for authentication. |
| 124 static bool UseOAuth2(); | 132 static bool UseOAuth2(); |
| 125 | 133 |
| 126 // Helpers to build the various suggestions URLs. These are static members | 134 // Helpers to build the various suggestions URLs. These are static members |
| 127 // rather than local functions in the .cc file to make them accessible to | 135 // rather than local functions in the .cc file to make them accessible to |
| 128 // tests. | 136 // tests. |
| 129 static GURL BuildSuggestionsURL(); | 137 static GURL BuildSuggestionsURL(); |
| 130 static std::string BuildSuggestionsBlacklistURLPrefix(); | 138 static std::string BuildSuggestionsBlacklistURLPrefix(); |
| 131 static GURL BuildSuggestionsBlacklistURL(const GURL& candidate_url); | 139 static GURL BuildSuggestionsBlacklistURL(const GURL& candidate_url); |
| 132 static GURL BuildSuggestionsBlacklistClearURL(); | 140 static GURL BuildSuggestionsBlacklistClearURL(); |
| 133 | 141 |
| 142 // sync_driver::SyncServiceObserver implementation. |
| 143 void OnStateChanged() override; |
| 144 |
| 134 // Sets default timestamp for suggestions which do not have expiry timestamp. | 145 // Sets default timestamp for suggestions which do not have expiry timestamp. |
| 135 void SetDefaultExpiryTimestamp(SuggestionsProfile* suggestions, | 146 void SetDefaultExpiryTimestamp(SuggestionsProfile* suggestions, |
| 136 int64_t timestamp_usec); | 147 int64_t timestamp_usec); |
| 137 | 148 |
| 138 // Issues a network request if there isn't already one happening. | 149 // Issues a network request if there isn't already one happening. |
| 139 void IssueRequestIfNoneOngoing(const GURL& url); | 150 void IssueRequestIfNoneOngoing(const GURL& url); |
| 140 | 151 |
| 141 // Issues a network request for suggestions (fetch, blacklist, or clear | 152 // Issues a network request for suggestions (fetch, blacklist, or clear |
| 142 // blacklist, depending on |url|). |access_token| is used only if OAuth2 | 153 // blacklist, depending on |url|). |access_token| is used only if OAuth2 |
| 143 // authentication is enabled. | 154 // authentication is enabled. |
| 144 void IssueSuggestionsRequest(const GURL& url, | 155 void IssueSuggestionsRequest(const GURL& url, |
| 145 const std::string& access_token); | 156 const std::string& access_token); |
| 146 | 157 |
| 147 // Creates a request to the suggestions service, properly setting headers. | 158 // Creates a request to the suggestions service, properly setting headers. |
| 148 // If OAuth2 authentication is enabled, |access_token| should be a valid | 159 // If OAuth2 authentication is enabled, |access_token| should be a valid |
| 149 // OAuth2 access token, and will be written into an auth header. | 160 // OAuth2 access token, and will be written into an auth header. |
| 150 scoped_ptr<net::URLFetcher> CreateSuggestionsRequest( | 161 scoped_ptr<net::URLFetcher> CreateSuggestionsRequest( |
| 151 const GURL& url, | 162 const GURL& url, |
| 152 const std::string& access_token); | 163 const std::string& access_token); |
| 153 | 164 |
| 154 // net::URLFetcherDelegate implementation. | 165 // net::URLFetcherDelegate implementation. |
| 155 // Called when fetch request completes. Parses the received suggestions data, | 166 // Called when fetch request completes. Parses the received suggestions data, |
| 156 // and dispatches them to callbacks stored in queue. | 167 // and dispatches them to callbacks stored in queue. |
| 157 void OnURLFetchComplete(const net::URLFetcher* source) override; | 168 void OnURLFetchComplete(const net::URLFetcher* source) override; |
| 158 | 169 |
| 159 // KeyedService implementation. | 170 // KeyedService implementation. |
| 160 void Shutdown() override; | 171 void Shutdown() override; |
| 161 | 172 |
| 162 // Loads the cached suggestions (or empty suggestions if no cache), applies | |
| 163 // the local blacklist, then calls the |callback|. | |
| 164 void ServeFromCache(const ResponseCallback& callback); | |
| 165 | |
| 166 // Schedules a blacklisting request if the local blacklist isn't empty. | 173 // Schedules a blacklisting request if the local blacklist isn't empty. |
| 167 void ScheduleBlacklistUpload(); | 174 void ScheduleBlacklistUpload(); |
| 168 | 175 |
| 169 // If the local blacklist isn't empty, picks a URL from it and issues a | 176 // If the local blacklist isn't empty, picks a URL from it and issues a |
| 170 // blacklist request for it. | 177 // blacklist request for it. |
| 171 void UploadOneFromBlacklist(); | 178 void UploadOneFromBlacklist(); |
| 172 | 179 |
| 173 // Updates |scheduling_delay_| based on the success of the last request. | 180 // Updates |scheduling_delay_| based on the success of the last request. |
| 174 void UpdateBlacklistDelay(bool last_request_successful); | 181 void UpdateBlacklistDelay(bool last_request_successful); |
| 175 | 182 |
| 176 // Adds extra data to suggestions profile. | 183 // Adds extra data to suggestions profile. |
| 177 void PopulateExtraData(SuggestionsProfile* suggestions); | 184 void PopulateExtraData(SuggestionsProfile* suggestions); |
| 178 | 185 |
| 179 // Test seams. | 186 // Test seams. |
| 180 base::TimeDelta blacklist_delay() const { return scheduling_delay_; } | 187 base::TimeDelta blacklist_delay() const { return scheduling_delay_; } |
| 181 void set_blacklist_delay(base::TimeDelta delay) { | 188 void set_blacklist_delay(base::TimeDelta delay) { |
| 182 scheduling_delay_ = delay; } | 189 scheduling_delay_ = delay; } |
| 183 | 190 |
| 184 base::ThreadChecker thread_checker_; | 191 base::ThreadChecker thread_checker_; |
| 185 | 192 |
| 193 sync_driver::SyncService* sync_service_; |
| 194 ScopedObserver<sync_driver::SyncService, sync_driver::SyncServiceObserver> |
| 195 sync_service_observer_; |
| 196 |
| 186 net::URLRequestContextGetter* url_request_context_; | 197 net::URLRequestContextGetter* url_request_context_; |
| 187 | 198 |
| 188 // The cache for the suggestions. | 199 // The cache for the suggestions. |
| 189 scoped_ptr<SuggestionsStore> suggestions_store_; | 200 scoped_ptr<SuggestionsStore> suggestions_store_; |
| 190 | 201 |
| 191 // Used to obtain server thumbnails, if available. | 202 // Used to obtain server thumbnails, if available. |
| 192 scoped_ptr<ImageManager> thumbnail_manager_; | 203 scoped_ptr<ImageManager> thumbnail_manager_; |
| 193 | 204 |
| 194 // The local cache for temporary blacklist, until uploaded to the server. | 205 // The local cache for temporary blacklist, until uploaded to the server. |
| 195 scoped_ptr<BlacklistStore> blacklist_store_; | 206 scoped_ptr<BlacklistStore> blacklist_store_; |
| 196 | 207 |
| 197 // Delay used when scheduling a blacklisting task. | 208 // Delay used when scheduling a blacklisting task. |
| 198 base::TimeDelta scheduling_delay_; | 209 base::TimeDelta scheduling_delay_; |
| 199 | 210 |
| 200 // Helper for fetching OAuth2 access tokens. | 211 // Helper for fetching OAuth2 access tokens. |
| 201 class AccessTokenFetcher; | 212 class AccessTokenFetcher; |
| 202 scoped_ptr<AccessTokenFetcher> token_fetcher_; | 213 scoped_ptr<AccessTokenFetcher> token_fetcher_; |
| 203 | 214 |
| 204 // Contains the current suggestions fetch request. Will only have a value | 215 // Contains the current suggestions fetch request. Will only have a value |
| 205 // while a request is pending, and will be reset by |OnURLFetchComplete| or | 216 // while a request is pending, and will be reset by |OnURLFetchComplete| or |
| 206 // if cancelled. | 217 // if cancelled. |
| 207 scoped_ptr<net::URLFetcher> pending_request_; | 218 scoped_ptr<net::URLFetcher> pending_request_; |
| 208 | 219 |
| 209 // The start time of the previous suggestions request. This is used to measure | 220 // The start time of the previous suggestions request. This is used to measure |
| 210 // the latency of requests. Initially zero. | 221 // the latency of requests. Initially zero. |
| 211 base::TimeTicks last_request_started_time_; | 222 base::TimeTicks last_request_started_time_; |
| 212 | 223 |
| 224 ResponseCallbackList callback_list_; |
| 225 |
| 213 // For callbacks may be run after destruction. | 226 // For callbacks may be run after destruction. |
| 214 base::WeakPtrFactory<SuggestionsService> weak_ptr_factory_; | 227 base::WeakPtrFactory<SuggestionsService> weak_ptr_factory_; |
| 215 | 228 |
| 216 DISALLOW_COPY_AND_ASSIGN(SuggestionsService); | 229 DISALLOW_COPY_AND_ASSIGN(SuggestionsService); |
| 217 }; | 230 }; |
| 218 | 231 |
| 219 } // namespace suggestions | 232 } // namespace suggestions |
| 220 | 233 |
| 221 #endif // COMPONENTS_SUGGESTIONS_SUGGESTIONS_SERVICE_H_ | 234 #endif // COMPONENTS_SUGGESTIONS_SUGGESTIONS_SERVICE_H_ |
| OLD | NEW |