| 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
|
|
|