| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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 #include "chrome/browser/profiles/profile_downloader.h" | 5 #include "chrome/browser/profiles/profile_downloader.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/json/json_reader.h" | 10 #include "base/json/json_reader.h" |
| 11 #include "base/logging.h" | 11 #include "base/logging.h" |
| 12 #include "base/message_loop/message_loop.h" | 12 #include "base/message_loop/message_loop.h" |
| 13 #include "base/strings/string_split.h" | 13 #include "base/strings/string_split.h" |
| 14 #include "base/strings/string_util.h" | 14 #include "base/strings/string_util.h" |
| 15 #include "base/strings/stringprintf.h" | 15 #include "base/strings/stringprintf.h" |
| 16 #include "base/values.h" | 16 #include "base/values.h" |
| 17 #include "chrome/browser/profiles/profile.h" | 17 #include "chrome/browser/profiles/profile.h" |
| 18 #include "chrome/browser/profiles/profile_downloader_delegate.h" | 18 #include "chrome/browser/profiles/profile_downloader_delegate.h" |
| 19 #include "chrome/browser/profiles/profile_manager.h" |
| 19 #include "chrome/browser/signin/profile_oauth2_token_service.h" | 20 #include "chrome/browser/signin/profile_oauth2_token_service.h" |
| 20 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h" | 21 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h" |
| 21 #include "content/public/browser/browser_thread.h" | 22 #include "content/public/browser/browser_thread.h" |
| 22 #include "google_apis/gaia/gaia_constants.h" | 23 #include "google_apis/gaia/gaia_constants.h" |
| 23 #include "google_apis/gaia/gaia_urls.h" | 24 #include "google_apis/gaia/gaia_urls.h" |
| 24 #include "net/base/load_flags.h" | 25 #include "net/base/load_flags.h" |
| 25 #include "net/url_request/url_fetcher.h" | 26 #include "net/url_request/url_fetcher.h" |
| 26 #include "net/url_request/url_request_status.h" | 27 #include "net/url_request/url_request_status.h" |
| 27 #include "skia/ext/image_operations.h" | 28 #include "skia/ext/image_operations.h" |
| 28 #include "url/gurl.h" | 29 #include "url/gurl.h" |
| 29 | 30 |
| 30 using content::BrowserThread; | 31 using content::BrowserThread; |
| 31 | 32 |
| 32 namespace { | 33 namespace { |
| 33 | 34 |
| 34 // Template for optional authorization header when using an OAuth access token. | 35 // Template for optional authorization header when using an OAuth access token. |
| 35 const char kAuthorizationHeader[] = | 36 const char kAuthorizationHeader[] = |
| 36 "Authorization: Bearer %s"; | 37 "Authorization: Bearer %s"; |
| 37 | 38 |
| 38 // URL requesting user info. | 39 // URL requesting user info. |
| 39 const char kUserEntryURL[] = | 40 const char kUserEntryURL[] = |
| 40 "https://www.googleapis.com/oauth2/v1/userinfo?alt=json"; | 41 "https://www.googleapis.com/oauth2/v1/userinfo?alt=json"; |
| 41 | 42 |
| 42 // OAuth scope for the user info API. | 43 // OAuth scope for the user info API. |
| 43 const char kAPIScope[] = "https://www.googleapis.com/auth/userinfo.profile"; | 44 const char kAPIScope[] = "https://www.googleapis.com/auth/userinfo.profile"; |
| 44 | 45 |
| 45 // Path in JSON dictionary to user's photo thumbnail URL. | 46 // Path in JSON dictionary to user's photo thumbnail URL. |
| 46 const char kPhotoThumbnailURLPath[] = "picture"; | 47 const char kPhotoThumbnailURLPath[] = "picture"; |
| 47 | 48 |
| 49 // Path in JSON dictionary to user's preferred locale. |
| 50 const char kLocalePath[] = "locale"; |
| 51 |
| 48 const char kNickNamePath[] = "name"; | 52 const char kNickNamePath[] = "name"; |
| 49 | 53 |
| 50 // Path format for specifying thumbnail's size. | 54 // Path format for specifying thumbnail's size. |
| 51 const char kThumbnailSizeFormat[] = "s%d-c"; | 55 const char kThumbnailSizeFormat[] = "s%d-c"; |
| 52 // Default thumbnail size. | 56 // Default thumbnail size. |
| 53 const int kDefaultThumbnailSize = 64; | 57 const int kDefaultThumbnailSize = 64; |
| 54 | 58 |
| 55 // Separator of URL path components. | 59 // Separator of URL path components. |
| 56 const char kURLPathSeparator = '/'; | 60 const char kURLPathSeparator = '/'; |
| 57 | 61 |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 113 return new_url->is_valid(); | 117 return new_url->is_valid(); |
| 114 } | 118 } |
| 115 | 119 |
| 116 // We can't set the image size, just use the default size. | 120 // We can't set the image size, just use the default size. |
| 117 *new_url = old_url; | 121 *new_url = old_url; |
| 118 return true; | 122 return true; |
| 119 } | 123 } |
| 120 | 124 |
| 121 } // namespace | 125 } // namespace |
| 122 | 126 |
| 123 // static | 127 // Parses the entry response and gets the name and profile image URL. |
| 124 bool ProfileDownloader::GetProfileNameAndImageURL(const std::string& data, | 128 // |data| should be the JSON formatted data return by the response. |
| 125 string16* nick_name, | 129 // Returns false to indicate a parsing error. |
| 126 std::string* url, | 130 bool ProfileDownloader::ParseProfileJSON(const std::string& data, |
| 127 int image_size) { | 131 string16* nick_name, |
| 132 std::string* url, |
| 133 int image_size, |
| 134 std::string* profile_locale) { |
| 128 DCHECK(nick_name); | 135 DCHECK(nick_name); |
| 129 DCHECK(url); | 136 DCHECK(url); |
| 130 *nick_name = string16(); | 137 *nick_name = string16(); |
| 131 *url = std::string(); | 138 *url = std::string(); |
| 139 *profile_locale = std::string(); |
| 132 | 140 |
| 133 int error_code = -1; | 141 int error_code = -1; |
| 134 std::string error_message; | 142 std::string error_message; |
| 135 scoped_ptr<base::Value> root_value(base::JSONReader::ReadAndReturnError( | 143 scoped_ptr<base::Value> root_value(base::JSONReader::ReadAndReturnError( |
| 136 data, base::JSON_PARSE_RFC, &error_code, &error_message)); | 144 data, base::JSON_PARSE_RFC, &error_code, &error_message)); |
| 137 if (!root_value) { | 145 if (!root_value) { |
| 138 LOG(ERROR) << "Error while parsing user entry response: " | 146 LOG(ERROR) << "Error while parsing user entry response: " |
| 139 << error_message; | 147 << error_message; |
| 140 return false; | 148 return false; |
| 141 } | 149 } |
| 142 if (!root_value->IsType(base::Value::TYPE_DICTIONARY)) { | 150 if (!root_value->IsType(base::Value::TYPE_DICTIONARY)) { |
| 143 LOG(ERROR) << "JSON root is not a dictionary: " | 151 LOG(ERROR) << "JSON root is not a dictionary: " |
| 144 << root_value->GetType(); | 152 << root_value->GetType(); |
| 145 return false; | 153 return false; |
| 146 } | 154 } |
| 147 base::DictionaryValue* root_dictionary = | 155 base::DictionaryValue* root_dictionary = |
| 148 static_cast<base::DictionaryValue*>(root_value.get()); | 156 static_cast<base::DictionaryValue*>(root_value.get()); |
| 149 | 157 |
| 158 root_dictionary->GetString(kLocalePath, profile_locale); |
| 150 root_dictionary->GetString(kNickNamePath, nick_name); | 159 root_dictionary->GetString(kNickNamePath, nick_name); |
| 151 | 160 |
| 152 std::string url_string; | 161 std::string url_string; |
| 153 if (root_dictionary->GetString(kPhotoThumbnailURLPath, &url_string)) { | 162 if (root_dictionary->GetString(kPhotoThumbnailURLPath, &url_string)) { |
| 154 GURL new_url; | 163 GURL new_url; |
| 155 if (!GetImageURLWithSize(GURL(url_string), image_size, &new_url)) { | 164 if (!GetImageURLWithSize(GURL(url_string), image_size, &new_url)) { |
| 156 LOG(ERROR) << "GetImageURLWithSize failed for url: " << url_string; | 165 LOG(ERROR) << "GetImageURLWithSize failed for url: " << url_string; |
| 157 return false; | 166 return false; |
| 158 } | 167 } |
| 159 *url = new_url.spec(); | 168 *url = new_url.spec(); |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 213 StartFetchingOAuth2AccessToken(); | 222 StartFetchingOAuth2AccessToken(); |
| 214 } else { | 223 } else { |
| 215 service->AddObserver(this); | 224 service->AddObserver(this); |
| 216 } | 225 } |
| 217 } | 226 } |
| 218 | 227 |
| 219 string16 ProfileDownloader::GetProfileFullName() const { | 228 string16 ProfileDownloader::GetProfileFullName() const { |
| 220 return profile_full_name_; | 229 return profile_full_name_; |
| 221 } | 230 } |
| 222 | 231 |
| 232 std::string ProfileDownloader::GetProfileLocale() const { |
| 233 return profile_locale_; |
| 234 } |
| 235 |
| 223 SkBitmap ProfileDownloader::GetProfilePicture() const { | 236 SkBitmap ProfileDownloader::GetProfilePicture() const { |
| 224 return profile_picture_; | 237 return profile_picture_; |
| 225 } | 238 } |
| 226 | 239 |
| 227 ProfileDownloader::PictureStatus ProfileDownloader::GetProfilePictureStatus() | 240 ProfileDownloader::PictureStatus ProfileDownloader::GetProfilePictureStatus() |
| 228 const { | 241 const { |
| 229 return picture_status_; | 242 return picture_status_; |
| 230 } | 243 } |
| 231 | 244 |
| 232 std::string ProfileDownloader::GetProfilePictureURL() const { | 245 std::string ProfileDownloader::GetProfilePictureURL() const { |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 272 DVLOG(1) << " Response code: " << source->GetResponseCode(); | 285 DVLOG(1) << " Response code: " << source->GetResponseCode(); |
| 273 DVLOG(1) << " Url: " << source->GetURL().spec(); | 286 DVLOG(1) << " Url: " << source->GetURL().spec(); |
| 274 delegate_->OnProfileDownloadFailure(this, network_error ? | 287 delegate_->OnProfileDownloadFailure(this, network_error ? |
| 275 ProfileDownloaderDelegate::NETWORK_ERROR : | 288 ProfileDownloaderDelegate::NETWORK_ERROR : |
| 276 ProfileDownloaderDelegate::SERVICE_ERROR); | 289 ProfileDownloaderDelegate::SERVICE_ERROR); |
| 277 return; | 290 return; |
| 278 } | 291 } |
| 279 | 292 |
| 280 if (source == user_entry_fetcher_.get()) { | 293 if (source == user_entry_fetcher_.get()) { |
| 281 std::string image_url; | 294 std::string image_url; |
| 282 if (!GetProfileNameAndImageURL(data, &profile_full_name_, &image_url, | 295 if (!ParseProfileJSON(data, |
| 283 delegate_->GetDesiredImageSideLength())) { | 296 &profile_full_name_, |
| 297 &image_url, |
| 298 delegate_->GetDesiredImageSideLength(), |
| 299 &profile_locale_)) { |
| 284 delegate_->OnProfileDownloadFailure( | 300 delegate_->OnProfileDownloadFailure( |
| 285 this, ProfileDownloaderDelegate::SERVICE_ERROR); | 301 this, ProfileDownloaderDelegate::SERVICE_ERROR); |
| 286 return; | 302 return; |
| 287 } | 303 } |
| 288 if (!delegate_->NeedsProfilePicture()) { | 304 if (!delegate_->NeedsProfilePicture()) { |
| 289 VLOG(1) << "Skipping profile picture download"; | 305 VLOG(1) << "Skipping profile picture download"; |
| 290 delegate_->OnProfileDownloadSuccess(this); | 306 delegate_->OnProfileDownloadSuccess(this); |
| 291 return; | 307 return; |
| 292 } | 308 } |
| 293 if (IsDefaultProfileImageURL(image_url)) { | 309 if (IsDefaultProfileImageURL(image_url)) { |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 367 // Callback for OAuth2TokenService::Request on failure. | 383 // Callback for OAuth2TokenService::Request on failure. |
| 368 void ProfileDownloader::OnGetTokenFailure( | 384 void ProfileDownloader::OnGetTokenFailure( |
| 369 const OAuth2TokenService::Request* request, | 385 const OAuth2TokenService::Request* request, |
| 370 const GoogleServiceAuthError& error) { | 386 const GoogleServiceAuthError& error) { |
| 371 DCHECK_EQ(request, oauth2_access_token_request_.get()); | 387 DCHECK_EQ(request, oauth2_access_token_request_.get()); |
| 372 oauth2_access_token_request_.reset(); | 388 oauth2_access_token_request_.reset(); |
| 373 LOG(WARNING) << "ProfileDownloader: token request using refresh token failed"; | 389 LOG(WARNING) << "ProfileDownloader: token request using refresh token failed"; |
| 374 delegate_->OnProfileDownloadFailure( | 390 delegate_->OnProfileDownloadFailure( |
| 375 this, ProfileDownloaderDelegate::TOKEN_ERROR); | 391 this, ProfileDownloaderDelegate::TOKEN_ERROR); |
| 376 } | 392 } |
| OLD | NEW |