| Index: chrome/browser/profiles/profile_downloader.cc
|
| diff --git a/chrome/browser/profiles/profile_downloader.cc b/chrome/browser/profiles/profile_downloader.cc
|
| index 15e8ceef496f45cb3a092c4c16b27a61c899b0d7..5fbb738cddbbd2f0ba70424e7b76f62b09cf605d 100644
|
| --- a/chrome/browser/profiles/profile_downloader.cc
|
| +++ b/chrome/browser/profiles/profile_downloader.cc
|
| @@ -21,6 +21,7 @@
|
| #include "chrome/browser/signin/signin_manager_factory.h"
|
| #include "components/signin/core/browser/profile_oauth2_token_service.h"
|
| #include "components/signin/core/browser/signin_manager.h"
|
| +#include "components/signin/core/common/profile_management_switches.h"
|
| #include "content/public/browser/browser_thread.h"
|
| #include "google_apis/gaia/gaia_constants.h"
|
| #include "google_apis/gaia/gaia_urls.h"
|
| @@ -38,17 +39,12 @@ namespace {
|
| const char kAuthorizationHeader[] =
|
| "Authorization: Bearer %s";
|
|
|
| -// URL requesting user info.
|
| -const char kUserEntryURL[] =
|
| - "https://www.googleapis.com/oauth2/v1/userinfo?alt=json";
|
| -
|
| -// OAuth scope for the user info API.
|
| -// For more info, see https://developers.google.com/accounts/docs/OAuth2LoginV1.
|
| -const char kAPIScope[] = "https://www.googleapis.com/auth/userinfo.profile";
|
| -
|
| // Path in JSON dictionary to user's photo thumbnail URL.
|
| const char kPhotoThumbnailURLPath[] = "picture";
|
|
|
| +// Path in JSON dictionary to user's hosted domain.
|
| +const char kHostedDomainPath[] = "hd";
|
| +
|
| // From the user info API, this field corresponds to the full name of the user.
|
| const char kFullNamePath[] = "name";
|
|
|
| @@ -133,42 +129,29 @@ bool GetImageURLWithSize(const GURL& old_url, int size, GURL* new_url) {
|
| // Parses the entry response and gets the name and profile image URL.
|
| // |data| should be the JSON formatted data return by the response.
|
| // Returns false to indicate a parsing error.
|
| -bool ProfileDownloader::ParseProfileJSON(const std::string& data,
|
| +bool ProfileDownloader::ParseProfileJSON(base::DictionaryValue* root_dictionary,
|
| base::string16* full_name,
|
| base::string16* given_name,
|
| std::string* url,
|
| int image_size,
|
| - std::string* profile_locale) {
|
| + std::string* profile_locale,
|
| + base::string16* hosted_domain) {
|
| DCHECK(full_name);
|
| DCHECK(given_name);
|
| DCHECK(url);
|
| DCHECK(profile_locale);
|
| + DCHECK(hosted_domain);
|
|
|
| *full_name = base::string16();
|
| *given_name = base::string16();
|
| *url = std::string();
|
| *profile_locale = std::string();
|
| -
|
| - int error_code = -1;
|
| - std::string error_message;
|
| - scoped_ptr<base::Value> root_value(base::JSONReader::ReadAndReturnError(
|
| - data, base::JSON_PARSE_RFC, &error_code, &error_message));
|
| - if (!root_value) {
|
| - LOG(ERROR) << "Error while parsing user entry response: "
|
| - << error_message;
|
| - return false;
|
| - }
|
| - if (!root_value->IsType(base::Value::TYPE_DICTIONARY)) {
|
| - LOG(ERROR) << "JSON root is not a dictionary: "
|
| - << root_value->GetType();
|
| - return false;
|
| - }
|
| - base::DictionaryValue* root_dictionary =
|
| - static_cast<base::DictionaryValue*>(root_value.get());
|
| + *hosted_domain = base::string16();
|
|
|
| root_dictionary->GetString(kFullNamePath, full_name);
|
| root_dictionary->GetString(kGivenNamePath, given_name);
|
| root_dictionary->GetString(kLocalePath, profile_locale);
|
| + root_dictionary->GetString(kHostedDomainPath, hosted_domain);
|
|
|
| std::string url_string;
|
| if (root_dictionary->GetString(kPhotoThumbnailURLPath, &url_string)) {
|
| @@ -247,6 +230,10 @@ void ProfileDownloader::StartForAccount(const std::string& account_id) {
|
| }
|
| }
|
|
|
| +base::string16 ProfileDownloader::GetProfileHostedDomain() const {
|
| + return profile_hosted_domain_;
|
| +}
|
| +
|
| base::string16 ProfileDownloader::GetProfileFullName() const {
|
| return profile_full_name_;
|
| }
|
| @@ -274,23 +261,18 @@ std::string ProfileDownloader::GetProfilePictureURL() const {
|
|
|
| void ProfileDownloader::StartFetchingImage() {
|
| VLOG(1) << "Fetching user entry with token: " << auth_token_;
|
| - user_entry_fetcher_.reset(net::URLFetcher::Create(
|
| - GURL(kUserEntryURL), net::URLFetcher::GET, this));
|
| - user_entry_fetcher_->SetRequestContext(
|
| - delegate_->GetBrowserProfile()->GetRequestContext());
|
| - user_entry_fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES |
|
| - net::LOAD_DO_NOT_SAVE_COOKIES);
|
| - if (!auth_token_.empty()) {
|
| - user_entry_fetcher_->SetExtraRequestHeaders(
|
| - base::StringPrintf(kAuthorizationHeader, auth_token_.c_str()));
|
| - }
|
| - user_entry_fetcher_->Start();
|
| + gaia_client_.reset(new gaia::GaiaOAuthClient(
|
| + delegate_->GetBrowserProfile()->GetRequestContext()));
|
| + gaia_client_->GetUserInfo(auth_token_, 0, this);
|
| }
|
|
|
| void ProfileDownloader::StartFetchingOAuth2AccessToken() {
|
| Profile* profile = delegate_->GetBrowserProfile();
|
| OAuth2TokenService::ScopeSet scopes;
|
| - scopes.insert(kAPIScope);
|
| + scopes.insert(GaiaConstants::kGoogleUserInfoProfile);
|
| + // Increase scope to get hd attribute to determine if lock should be enabled.
|
| + if (switches::IsNewProfileManagement())
|
| + scopes.insert(GaiaConstants::kGoogleUserInfoEmail);
|
| ProfileOAuth2TokenService* token_service =
|
| ProfileOAuth2TokenServiceFactory::GetForProfile(profile);
|
| oauth2_access_token_request_ = token_service->StartRequest(
|
| @@ -307,6 +289,65 @@ ProfileDownloader::~ProfileDownloader() {
|
| service->RemoveObserver(this);
|
| }
|
|
|
| +void ProfileDownloader::OnGetUserInfoResponse(
|
| + scoped_ptr<base::DictionaryValue> user_info) {
|
| + std::string image_url;
|
| + if (!ParseProfileJSON(user_info.get(),
|
| + &profile_full_name_,
|
| + &profile_given_name_,
|
| + &image_url,
|
| + delegate_->GetDesiredImageSideLength(),
|
| + &profile_locale_,
|
| + &profile_hosted_domain_)) {
|
| + delegate_->OnProfileDownloadFailure(
|
| + this, ProfileDownloaderDelegate::SERVICE_ERROR);
|
| + return;
|
| + }
|
| + if (!delegate_->NeedsProfilePicture()) {
|
| + VLOG(1) << "Skipping profile picture download";
|
| + delegate_->OnProfileDownloadSuccess(this);
|
| + return;
|
| + }
|
| + if (IsDefaultProfileImageURL(image_url)) {
|
| + VLOG(1) << "User has default profile picture";
|
| + picture_status_ = PICTURE_DEFAULT;
|
| + delegate_->OnProfileDownloadSuccess(this);
|
| + return;
|
| + }
|
| + if (!image_url.empty() && image_url == delegate_->GetCachedPictureURL()) {
|
| + VLOG(1) << "Picture URL matches cached picture URL";
|
| + picture_status_ = PICTURE_CACHED;
|
| + delegate_->OnProfileDownloadSuccess(this);
|
| + return;
|
| + }
|
| + VLOG(1) << "Fetching profile image from " << image_url;
|
| + picture_url_ = image_url;
|
| + profile_image_fetcher_.reset(net::URLFetcher::Create(
|
| + GURL(image_url), net::URLFetcher::GET, this));
|
| + profile_image_fetcher_->SetRequestContext(
|
| + delegate_->GetBrowserProfile()->GetRequestContext());
|
| + profile_image_fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES |
|
| + net::LOAD_DO_NOT_SAVE_COOKIES);
|
| + if (!auth_token_.empty()) {
|
| + profile_image_fetcher_->SetExtraRequestHeaders(
|
| + base::StringPrintf(kAuthorizationHeader, auth_token_.c_str()));
|
| + }
|
| + profile_image_fetcher_->Start();
|
| +}
|
| +
|
| +void ProfileDownloader::OnOAuthError() {
|
| + LOG(WARNING) << "OnOAuthError: Fetching profile data failed";
|
| + delegate_->OnProfileDownloadFailure(
|
| + this, ProfileDownloaderDelegate::SERVICE_ERROR);
|
| +}
|
| +
|
| +void ProfileDownloader::OnNetworkError(int response_code) {
|
| + LOG(WARNING) << "OnNetworkError: Fetching profile data failed";
|
| + DVLOG(1) << " Response code: " << response_code;
|
| + delegate_->OnProfileDownloadFailure(
|
| + this, ProfileDownloaderDelegate::NETWORK_ERROR);
|
| +}
|
| +
|
| void ProfileDownloader::OnURLFetchComplete(const net::URLFetcher* source) {
|
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| std::string data;
|
| @@ -325,56 +366,12 @@ void ProfileDownloader::OnURLFetchComplete(const net::URLFetcher* source) {
|
| return;
|
| }
|
|
|
| - if (source == user_entry_fetcher_.get()) {
|
| - std::string image_url;
|
| - if (!ParseProfileJSON(data,
|
| - &profile_full_name_,
|
| - &profile_given_name_,
|
| - &image_url,
|
| - delegate_->GetDesiredImageSideLength(),
|
| - &profile_locale_)) {
|
| - delegate_->OnProfileDownloadFailure(
|
| - this, ProfileDownloaderDelegate::SERVICE_ERROR);
|
| - return;
|
| - }
|
| - if (!delegate_->NeedsProfilePicture()) {
|
| - VLOG(1) << "Skipping profile picture download";
|
| - delegate_->OnProfileDownloadSuccess(this);
|
| - return;
|
| - }
|
| - if (IsDefaultProfileImageURL(image_url)) {
|
| - VLOG(1) << "User has default profile picture";
|
| - picture_status_ = PICTURE_DEFAULT;
|
| - delegate_->OnProfileDownloadSuccess(this);
|
| - return;
|
| - }
|
| - if (!image_url.empty() && image_url == delegate_->GetCachedPictureURL()) {
|
| - VLOG(1) << "Picture URL matches cached picture URL";
|
| - picture_status_ = PICTURE_CACHED;
|
| - delegate_->OnProfileDownloadSuccess(this);
|
| - return;
|
| - }
|
| - VLOG(1) << "Fetching profile image from " << image_url;
|
| - picture_url_ = image_url;
|
| - profile_image_fetcher_.reset(net::URLFetcher::Create(
|
| - GURL(image_url), net::URLFetcher::GET, this));
|
| - profile_image_fetcher_->SetRequestContext(
|
| - delegate_->GetBrowserProfile()->GetRequestContext());
|
| - profile_image_fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES |
|
| - net::LOAD_DO_NOT_SAVE_COOKIES);
|
| - if (!auth_token_.empty()) {
|
| - profile_image_fetcher_->SetExtraRequestHeaders(
|
| - base::StringPrintf(kAuthorizationHeader, auth_token_.c_str()));
|
| - }
|
| - profile_image_fetcher_->Start();
|
| - } else if (source == profile_image_fetcher_.get()) {
|
| - VLOG(1) << "Decoding the image...";
|
| - scoped_refptr<ImageDecoder> image_decoder = new ImageDecoder(
|
| - this, data, ImageDecoder::DEFAULT_CODEC);
|
| - scoped_refptr<base::MessageLoopProxy> task_runner =
|
| - BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI);
|
| - image_decoder->Start(task_runner);
|
| - }
|
| + VLOG(1) << "Decoding the image...";
|
| + scoped_refptr<ImageDecoder> image_decoder = new ImageDecoder(
|
| + this, data, ImageDecoder::DEFAULT_CODEC);
|
| + scoped_refptr<base::MessageLoopProxy> task_runner =
|
| + BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI);
|
| + image_decoder->Start(task_runner);
|
| }
|
|
|
| void ProfileDownloader::OnImageDecoded(const ImageDecoder* decoder,
|
|
|