Index: chrome/browser/history/web_history_service.cc |
diff --git a/chrome/browser/history/web_history_service.cc b/chrome/browser/history/web_history_service.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..87420b37a411dabd86bad6bfb9b3165edacc361e |
--- /dev/null |
+++ b/chrome/browser/history/web_history_service.cc |
@@ -0,0 +1,174 @@ |
+// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "chrome/browser/history/web_history_service.h" |
+ |
+#include "chrome/browser/content_settings/cookie_settings.h" |
+#include "chrome/browser/profiles/profile_dependency_manager.h" |
+#include "chrome/browser/profiles/profile.h" |
+#include "chrome/browser/signin/token_service.h" |
+#include "chrome/browser/signin/token_service_factory.h" |
+#include "chrome/common/chrome_notification_types.h" |
+#include "chrome/common/net/gaia/gaia_constants.h" |
+#include "chrome/common/net/gaia/gaia_urls.h" |
+#include "chrome/common/net/gaia/oauth2_access_token_fetcher.h" |
+#include "content/public/browser/notification_details.h" |
+#include "content/public/browser/notification_source.h" |
+#include "net/base/load_flags.h" |
+ |
+namespace { |
+ |
+const char kWebHistoryOAuthScope[] = "https://www.googleapis.com/auth/userinfo.profile"; |
+ |
+// The maximum number of retries for the URLFetcher requests. |
+const size_t kMaxRetries = 1; |
+ |
+// The number of hours to delay before retrying authentication on failure. |
+// FIXME: This value was just copied from ChromeToMobileService. |
+const size_t kAuthRetryDelayHours = 6; |
+ |
+// Used for creating and fetching a per-profile instance of the |
+// WebHistoryService. |
+class WebHistoryServiceFactory : public ProfileKeyedServiceFactory { |
+ public: |
+ // Get the singleton instance of the factory. |
+ static WebHistoryServiceFactory* GetInstance() { |
+ return Singleton<WebHistoryServiceFactory>::get(); |
+ } |
+ |
+ // Get the WebHistoryService for |profile|, creating one if needed. |
+ static history::WebHistoryService* GetForProfile(Profile* profile) { |
+ return static_cast<history::WebHistoryService*>( |
+ GetInstance()->GetServiceForProfile(profile, true)); |
+ } |
+ |
+ protected: |
+ // Overridden from ProfileKeyedServiceFactory. |
+ virtual ProfileKeyedService* BuildServiceInstanceFor( |
+ Profile* profile) const OVERRIDE { |
+ // Ensure that the service is not instantiated or used if it is disabled. |
+// if (!ChromeToMobileService::IsChromeToMobileEnabled()) |
+// return NULL; |
+ |
+ return new history::WebHistoryService(profile); |
+ } |
+ |
+ private: |
+ friend struct DefaultSingletonTraits<WebHistoryServiceFactory>; |
+ |
+ explicit WebHistoryServiceFactory() |
+ : ProfileKeyedServiceFactory("WebHistoryServiceFactory", |
+ ProfileDependencyManager::GetInstance()) { |
+ DependsOn(TokenServiceFactory::GetInstance()); |
+ DependsOn(CookieSettings::Factory::GetInstance()); |
+ } |
+ |
+ virtual ~WebHistoryServiceFactory() {}; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(WebHistoryServiceFactory); |
+}; |
+ |
+} // namespace |
+ |
+namespace history { |
+ |
+// static |
+WebHistoryService* WebHistoryService::GetForProfile(Profile* profile) { |
+ return WebHistoryServiceFactory::GetForProfile(profile); |
+} |
+ |
+WebHistoryService::WebHistoryService(Profile* profile) |
+ : profile_(profile) { |
+ // Get an access token as soon as the Gaia login refresh token is available. |
+ TokenService* service = TokenServiceFactory::GetForProfile(profile_); |
+ registrar_.Add(this, chrome::NOTIFICATION_TOKEN_AVAILABLE, |
+ content::Source<TokenService>(service)); |
+ if (service->HasOAuthLoginToken()) |
+ RefreshAccessToken(); |
+} |
+ |
+WebHistoryService::~WebHistoryService() { |
+} |
+ |
+// FIXME: This is copied from ChromeToMobileService. Could it be shared somehow? |
+void WebHistoryService::RefreshAccessToken() { |
+ if (access_token_fetcher_.get()) |
+ return; |
+ |
+ std::string token = TokenServiceFactory::GetForProfile(profile_)-> |
+ GetOAuth2LoginRefreshToken(); |
+ if (token.empty()) |
+ return; |
+ |
+ auth_retry_timer_.Stop(); |
+ access_token_fetcher_.reset( |
+ new OAuth2AccessTokenFetcher(this, profile_->GetRequestContext())); |
+ std::vector<std::string> scopes(1, kWebHistoryOAuthScope); |
+ GaiaUrls* gaia_urls = GaiaUrls::GetInstance(); |
+ access_token_fetcher_->Start(gaia_urls->oauth2_chrome_client_id(), |
+ gaia_urls->oauth2_chrome_client_secret(), token, scopes); |
+} |
+ |
+void WebHistoryService::Observe( |
+ int type, |
+ const content::NotificationSource& source, |
+ const content::NotificationDetails& details) { |
+ DCHECK_EQ(type, chrome::NOTIFICATION_TOKEN_AVAILABLE); |
+ TokenService::TokenAvailableDetails* token_details = |
+ content::Details<TokenService::TokenAvailableDetails>(details).ptr(); |
+ if (token_details->service() == GaiaConstants::kGaiaOAuth2LoginRefreshToken) |
+ RefreshAccessToken(); |
+} |
+ |
+void WebHistoryService::OnURLFetchComplete(const net::URLFetcher* source) { |
+ std::string data; |
+ url_fetcher_->GetResponseAsString(&data); |
+ url_fetcher_.reset(); |
+ |
+ query_history_callback_.Run(); |
+} |
+ |
+void WebHistoryService::OnGetTokenSuccess( |
+ const std::string& access_token) { |
+ DCHECK(!access_token.empty()); |
+ access_token_fetcher_.reset(); |
+ auth_retry_timer_.Stop(); |
+ access_token_ = access_token; |
+} |
+ |
+void WebHistoryService::OnGetTokenFailure( |
+ const GoogleServiceAuthError& error) { |
+ access_token_fetcher_.reset(); |
+ auth_retry_timer_.Stop(); |
+ auth_retry_timer_.Start( |
+ FROM_HERE, base::TimeDelta::FromHours(kAuthRetryDelayHours), |
+ this, &WebHistoryService::RefreshAccessToken); |
+} |
+ |
+ void WebHistoryService::QueryHistory( |
+ const string16& text_query, |
+ const QueryOptions& options, |
+ CancelableRequestConsumerBase* consumer, |
+ const QueryWebHistoryCallback& callback) { |
+ DCHECK(!access_token_.empty()); |
+ GURL url("https://www.googleapis.com/oauth2/v2/userinfo"); |
+ |
+ url_fetcher_.reset( |
+ content::URLFetcher::Create(url, content::URLFetcher::GET, this)); |
+ url_fetcher_->SetRequestContext(profile_->GetRequestContext()); |
+ url_fetcher_->SetMaxRetries(kMaxRetries); |
+ |
+ url_fetcher_->SetExtraRequestHeaders("Authorization: OAuth " + access_token_ + "\r\n"); |
+ LOG(WARNING) << "Authorization: OAuth " + access_token_; |
+ /* |
+ url_fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES | |
+ net::LOAD_DO_NOT_SAVE_COOKIES); |
+ */ |
+ |
+// url_fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SAVE_COOKIES); |
+ query_history_callback_ = callback; |
+ url_fetcher_->Start(); |
+} |
+ |
+} // namespace history |