Chromium Code Reviews| Index: google_apis/gaia/merge_session_helper.cc |
| diff --git a/google_apis/gaia/merge_session_helper.cc b/google_apis/gaia/merge_session_helper.cc |
| index cf2fa95730dd27bfc2f9335e1841969af0ae9259..63609b806a83a1e4617cbc6cb5be5ff7d5ad5fd5 100644 |
| --- a/google_apis/gaia/merge_session_helper.cc |
| +++ b/google_apis/gaia/merge_session_helper.cc |
| @@ -4,19 +4,149 @@ |
| #include "google_apis/gaia/merge_session_helper.h" |
| +#include <vector> |
| + |
| +#include "base/json/json_reader.h" |
| +#include "base/stl_util.h" |
| +#include "base/strings/string_util.h" |
| +#include "base/strings/stringprintf.h" |
| +#include "base/time/time.h" |
| +#include "base/values.h" |
| #include "google_apis/gaia/gaia_auth_fetcher.h" |
| #include "google_apis/gaia/gaia_constants.h" |
| #include "google_apis/gaia/gaia_urls.h" |
| #include "google_apis/gaia/oauth2_token_service.h" |
| +#include "net/base/load_flags.h" |
| +#include "net/http/http_status_code.h" |
| #include "net/url_request/url_fetcher.h" |
| #include "net/url_request/url_fetcher_delegate.h" |
| +MergeSessionHelper::ExternalCcResultFetcher::ExternalCcResultFetcher( |
| + MergeSessionHelper* helper) : helper_(helper) { |
| + DCHECK(helper_); |
| +} |
| + |
| +MergeSessionHelper::ExternalCcResultFetcher::~ExternalCcResultFetcher() { |
| + CleanupTransientState(); |
| +} |
| + |
| +std::string MergeSessionHelper::ExternalCcResultFetcher::GetExternalCcResult() { |
| + std::vector<std::string> results; |
| + for (ResultMap::const_iterator it = results_.begin(); it != results_.end(); |
| + ++it) { |
| + results.push_back(it->first + ":" + it->second); |
| + } |
| + return JoinString(results, ","); |
| +} |
| + |
| +void MergeSessionHelper::ExternalCcResultFetcher::Start() { |
| + CleanupTransientState(); |
| + results_.clear(); |
| + gaia_auth_fetcher_.reset( |
| + new GaiaAuthFetcher(this, GaiaConstants::kChromeSource, |
| + helper_->request_context())); |
| + gaia_auth_fetcher_->StartGetCheckConnectionInfo(); |
| +} |
| + |
| +void |
| +MergeSessionHelper::ExternalCcResultFetcher::OnGetCheckConnectionInfoSuccess( |
| + const std::string& data) { |
| + base::Value* value = base::JSONReader::Read(data); |
| + const base::ListValue* list; |
| + if (!value || !value->GetAsList(&list)) |
| + return; |
| + |
| + // Start a fetcher for each connection URL that needs to be checked. |
| + for (size_t i = 0; i < list->GetSize(); ++i) { |
| + const base::DictionaryValue* dict; |
| + if (list->GetDictionary(i, &dict)) { |
| + std::string token; |
| + std::string url; |
| + if (dict->GetString("carryBackToken", &token) && |
| + dict->GetString("url", &url)) { |
| + results_[token] = "null"; |
| + net::URLFetcher* fetcher = CreateFetcher(GURL(url)); |
| + fetchers_[fetcher->GetOriginalURL()] = std::make_pair(token, fetcher); |
| + fetcher->Start(); |
| + } |
| + } |
| + } |
| + |
| + // Some fetches may timeout. Start a timer to decide when the result fetcher |
| + // has waited long enough. |
| + // TODO(rogerta): I have no idea how to long to wait before timing out. |
|
guohui
2014/08/05 19:14:07
nits: extra to
Roger Tawa OOO till Jul 10th
2014/08/08 19:29:53
Done.
|
| + // Gaia folks say this should take no more than 2 second even in mobile. |
| + // This will need to be tweaked. |
| + timer_.Start(FROM_HERE, base::TimeDelta::FromSeconds(5), |
| + this, &MergeSessionHelper::ExternalCcResultFetcher::Timeout); |
| +} |
| + |
| +net::URLFetcher* MergeSessionHelper::ExternalCcResultFetcher::CreateFetcher( |
| + const GURL& url) { |
| + net::URLFetcher* fetcher = net::URLFetcher::Create( |
| + 0, |
| + url, |
| + net::URLFetcher::GET, |
| + this); |
| + fetcher->SetRequestContext(helper_->request_context()); |
| + fetcher->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES | |
| + net::LOAD_DO_NOT_SAVE_COOKIES); |
| + |
| + // Fetchers are sometimes cancelled because a network change was detected, |
| + // especially at startup and after sign-in on ChromeOS. |
| + fetcher->SetAutomaticallyRetryOnNetworkChanges(1); |
| + return fetcher; |
| +} |
| + |
| +void MergeSessionHelper::ExternalCcResultFetcher::OnURLFetchComplete( |
| + const net::URLFetcher* source) { |
| + const GURL& url = source->GetOriginalURL(); |
| + const net::URLRequestStatus& status = source->GetStatus(); |
| + int response_code = source->GetResponseCode(); |
| + if (status.is_success() && response_code == net::HTTP_OK && |
| + fetchers_.count(url) > 0) { |
| + std::string data; |
| + source->GetResponseAsString(&data); |
| + // Only up to the first 16 characters of the response are important. |
| + // Truncate if needed. |
| + if (data.size() > 16) |
| + data.resize(16); |
| + results_[fetchers_[url].first] = data; |
| + |
| + // If we have received all the responses we expect, cancel the timer and |
| + // report the result. |
| + DCHECK_EQ(source, fetchers_[url].second); |
| + fetchers_.erase(url); |
| + delete source; |
| + if (fetchers_.size() == 0) { |
| + timer_.Stop(); |
| + CleanupTransientState(); |
| + } |
| + } |
| +} |
| + |
| +void MergeSessionHelper::ExternalCcResultFetcher::Timeout() { |
| + CleanupTransientState(); |
| +} |
| + |
| +void MergeSessionHelper::ExternalCcResultFetcher::CleanupTransientState() { |
| + gaia_auth_fetcher_.reset(); |
| + |
| + for (URLToTokenAndFetcher::const_iterator it = fetchers_.begin(); |
| + it != fetchers_.end(); ++it) { |
| + delete it->second.second; |
| + } |
| + fetchers_.clear(); |
| +} |
| + |
| + |
| MergeSessionHelper::MergeSessionHelper( |
| OAuth2TokenService* token_service, |
| net::URLRequestContextGetter* request_context, |
| Observer* observer) |
| : token_service_(token_service), |
| - request_context_(request_context) { |
| + request_context_(request_context), |
| + result_fetcher_(this) { |
| if (observer) |
| AddObserver(observer); |
| } |
| @@ -111,6 +241,10 @@ void MergeSessionHelper::SignalComplete( |
| MergeSessionCompleted(account_id, error)); |
| } |
| +void MergeSessionHelper::StartFetchingExternalCcResult() { |
| + result_fetcher_.Start(); |
| +} |
| + |
| void MergeSessionHelper::StartLogOutUrlFetch() { |
| DCHECK(accounts_.front().empty()); |
| VLOG(1) << "MergeSessionHelper::StartLogOutUrlFetch"; |
| @@ -127,7 +261,8 @@ void MergeSessionHelper::OnUbertokenSuccess(const std::string& uber_token) { |
| gaia_auth_fetcher_.reset(new GaiaAuthFetcher(this, |
| GaiaConstants::kChromeSource, |
| request_context_)); |
| - gaia_auth_fetcher_->StartMergeSession(uber_token); |
| + gaia_auth_fetcher_->StartMergeSession(uber_token, |
| + result_fetcher_.GetExternalCcResult()); |
|
guohui
2014/08/05 19:14:07
is it guaranteed that all eternal cc results are a
guohui
2014/08/06 20:52:27
could you also add comments here that it is not gu
Roger Tawa OOO till Jul 10th
2014/08/08 19:29:53
Nope. We don't want to delay the merge session, s
Roger Tawa OOO till Jul 10th
2014/08/08 19:29:53
Done.
|
| } |
| void MergeSessionHelper::OnUbertokenFailure( |