| 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" |
| (...skipping 15 matching lines...) Expand all Loading... |
| 44 const char kAPIScope[] = "https://www.googleapis.com/auth/userinfo.profile"; | 45 const char kAPIScope[] = "https://www.googleapis.com/auth/userinfo.profile"; |
| 45 | 46 |
| 46 // Path in JSON dictionary to user's photo thumbnail URL. | 47 // Path in JSON dictionary to user's photo thumbnail URL. |
| 47 const char kPhotoThumbnailURLPath[] = "picture"; | 48 const char kPhotoThumbnailURLPath[] = "picture"; |
| 48 | 49 |
| 49 // From the user info API, this field corresponds to the full name of the user. | 50 // From the user info API, this field corresponds to the full name of the user. |
| 50 const char kFullNamePath[] = "name"; | 51 const char kFullNamePath[] = "name"; |
| 51 | 52 |
| 52 const char kGivenNamePath[] = "given_name"; | 53 const char kGivenNamePath[] = "given_name"; |
| 53 | 54 |
| 55 // Path in JSON dictionary to user's preferred locale. |
| 56 const char kLocalePath[] = "locale"; |
| 57 |
| 54 // Path format for specifying thumbnail's size. | 58 // Path format for specifying thumbnail's size. |
| 55 const char kThumbnailSizeFormat[] = "s%d-c"; | 59 const char kThumbnailSizeFormat[] = "s%d-c"; |
| 56 // Default thumbnail size. | 60 // Default thumbnail size. |
| 57 const int kDefaultThumbnailSize = 64; | 61 const int kDefaultThumbnailSize = 64; |
| 58 | 62 |
| 59 // Separator of URL path components. | 63 // Separator of URL path components. |
| 60 const char kURLPathSeparator = '/'; | 64 const char kURLPathSeparator = '/'; |
| 61 | 65 |
| 62 // Photo ID of the Picasa Web Albums profile picture (base64 of 0). | 66 // Photo ID of the Picasa Web Albums profile picture (base64 of 0). |
| 63 const char kPicasaPhotoId[] = "AAAAAAAAAAA"; | 67 const char kPicasaPhotoId[] = "AAAAAAAAAAA"; |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 117 return new_url->is_valid(); | 121 return new_url->is_valid(); |
| 118 } | 122 } |
| 119 | 123 |
| 120 // We can't set the image size, just use the default size. | 124 // We can't set the image size, just use the default size. |
| 121 *new_url = old_url; | 125 *new_url = old_url; |
| 122 return true; | 126 return true; |
| 123 } | 127 } |
| 124 | 128 |
| 125 } // namespace | 129 } // namespace |
| 126 | 130 |
| 127 // static | 131 // Parses the entry response and gets the name and profile image URL. |
| 128 bool ProfileDownloader::GetProfileNameAndImageURL(const std::string& data, | 132 // |data| should be the JSON formatted data return by the response. |
| 129 string16* full_name, | 133 // Returns false to indicate a parsing error. |
| 130 string16* given_name, | 134 bool ProfileDownloader::ParseProfileJSON(const std::string& data, |
| 131 std::string* url, | 135 string16* full_name, |
| 132 int image_size) { | 136 string16* given_name, |
| 137 std::string* url, |
| 138 int image_size, |
| 139 std::string* profile_locale) { |
| 133 DCHECK(full_name); | 140 DCHECK(full_name); |
| 134 DCHECK(given_name); | 141 DCHECK(given_name); |
| 135 DCHECK(url); | 142 DCHECK(url); |
| 143 DCHECK(profile_locale); |
| 144 |
| 136 *full_name = string16(); | 145 *full_name = string16(); |
| 137 *given_name = string16(); | 146 *given_name = string16(); |
| 138 *url = std::string(); | 147 *url = std::string(); |
| 148 *profile_locale = std::string(); |
| 139 | 149 |
| 140 int error_code = -1; | 150 int error_code = -1; |
| 141 std::string error_message; | 151 std::string error_message; |
| 142 scoped_ptr<base::Value> root_value(base::JSONReader::ReadAndReturnError( | 152 scoped_ptr<base::Value> root_value(base::JSONReader::ReadAndReturnError( |
| 143 data, base::JSON_PARSE_RFC, &error_code, &error_message)); | 153 data, base::JSON_PARSE_RFC, &error_code, &error_message)); |
| 144 if (!root_value) { | 154 if (!root_value) { |
| 145 LOG(ERROR) << "Error while parsing user entry response: " | 155 LOG(ERROR) << "Error while parsing user entry response: " |
| 146 << error_message; | 156 << error_message; |
| 147 return false; | 157 return false; |
| 148 } | 158 } |
| 149 if (!root_value->IsType(base::Value::TYPE_DICTIONARY)) { | 159 if (!root_value->IsType(base::Value::TYPE_DICTIONARY)) { |
| 150 LOG(ERROR) << "JSON root is not a dictionary: " | 160 LOG(ERROR) << "JSON root is not a dictionary: " |
| 151 << root_value->GetType(); | 161 << root_value->GetType(); |
| 152 return false; | 162 return false; |
| 153 } | 163 } |
| 154 base::DictionaryValue* root_dictionary = | 164 base::DictionaryValue* root_dictionary = |
| 155 static_cast<base::DictionaryValue*>(root_value.get()); | 165 static_cast<base::DictionaryValue*>(root_value.get()); |
| 156 | 166 |
| 157 root_dictionary->GetString(kFullNamePath, full_name); | 167 root_dictionary->GetString(kFullNamePath, full_name); |
| 158 root_dictionary->GetString(kGivenNamePath, given_name); | 168 root_dictionary->GetString(kGivenNamePath, given_name); |
| 169 root_dictionary->GetString(kLocalePath, profile_locale); |
| 159 | 170 |
| 160 std::string url_string; | 171 std::string url_string; |
| 161 if (root_dictionary->GetString(kPhotoThumbnailURLPath, &url_string)) { | 172 if (root_dictionary->GetString(kPhotoThumbnailURLPath, &url_string)) { |
| 162 GURL new_url; | 173 GURL new_url; |
| 163 if (!GetImageURLWithSize(GURL(url_string), image_size, &new_url)) { | 174 if (!GetImageURLWithSize(GURL(url_string), image_size, &new_url)) { |
| 164 LOG(ERROR) << "GetImageURLWithSize failed for url: " << url_string; | 175 LOG(ERROR) << "GetImageURLWithSize failed for url: " << url_string; |
| 165 return false; | 176 return false; |
| 166 } | 177 } |
| 167 *url = new_url.spec(); | 178 *url = new_url.spec(); |
| 168 } | 179 } |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 226 } | 237 } |
| 227 | 238 |
| 228 string16 ProfileDownloader::GetProfileFullName() const { | 239 string16 ProfileDownloader::GetProfileFullName() const { |
| 229 return profile_full_name_; | 240 return profile_full_name_; |
| 230 } | 241 } |
| 231 | 242 |
| 232 string16 ProfileDownloader::GetProfileGivenName() const { | 243 string16 ProfileDownloader::GetProfileGivenName() const { |
| 233 return profile_given_name_; | 244 return profile_given_name_; |
| 234 } | 245 } |
| 235 | 246 |
| 247 std::string ProfileDownloader::GetProfileLocale() const { |
| 248 return profile_locale_; |
| 249 } |
| 250 |
| 236 SkBitmap ProfileDownloader::GetProfilePicture() const { | 251 SkBitmap ProfileDownloader::GetProfilePicture() const { |
| 237 return profile_picture_; | 252 return profile_picture_; |
| 238 } | 253 } |
| 239 | 254 |
| 240 ProfileDownloader::PictureStatus ProfileDownloader::GetProfilePictureStatus() | 255 ProfileDownloader::PictureStatus ProfileDownloader::GetProfilePictureStatus() |
| 241 const { | 256 const { |
| 242 return picture_status_; | 257 return picture_status_; |
| 243 } | 258 } |
| 244 | 259 |
| 245 std::string ProfileDownloader::GetProfilePictureURL() const { | 260 std::string ProfileDownloader::GetProfilePictureURL() const { |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 286 DVLOG(1) << " Response code: " << source->GetResponseCode(); | 301 DVLOG(1) << " Response code: " << source->GetResponseCode(); |
| 287 DVLOG(1) << " Url: " << source->GetURL().spec(); | 302 DVLOG(1) << " Url: " << source->GetURL().spec(); |
| 288 delegate_->OnProfileDownloadFailure(this, network_error ? | 303 delegate_->OnProfileDownloadFailure(this, network_error ? |
| 289 ProfileDownloaderDelegate::NETWORK_ERROR : | 304 ProfileDownloaderDelegate::NETWORK_ERROR : |
| 290 ProfileDownloaderDelegate::SERVICE_ERROR); | 305 ProfileDownloaderDelegate::SERVICE_ERROR); |
| 291 return; | 306 return; |
| 292 } | 307 } |
| 293 | 308 |
| 294 if (source == user_entry_fetcher_.get()) { | 309 if (source == user_entry_fetcher_.get()) { |
| 295 std::string image_url; | 310 std::string image_url; |
| 296 if (!GetProfileNameAndImageURL(data, | 311 if (!ParseProfileJSON(data, |
| 297 &profile_full_name_, | 312 &profile_full_name_, |
| 298 &profile_given_name_, | 313 &profile_given_name_, |
| 299 &image_url, | 314 &image_url, |
| 300 delegate_->GetDesiredImageSideLength())) { | 315 delegate_->GetDesiredImageSideLength(), |
| 316 &profile_locale_)) { |
| 301 delegate_->OnProfileDownloadFailure( | 317 delegate_->OnProfileDownloadFailure( |
| 302 this, ProfileDownloaderDelegate::SERVICE_ERROR); | 318 this, ProfileDownloaderDelegate::SERVICE_ERROR); |
| 303 return; | 319 return; |
| 304 } | 320 } |
| 305 if (!delegate_->NeedsProfilePicture()) { | 321 if (!delegate_->NeedsProfilePicture()) { |
| 306 VLOG(1) << "Skipping profile picture download"; | 322 VLOG(1) << "Skipping profile picture download"; |
| 307 delegate_->OnProfileDownloadSuccess(this); | 323 delegate_->OnProfileDownloadSuccess(this); |
| 308 return; | 324 return; |
| 309 } | 325 } |
| 310 if (IsDefaultProfileImageURL(image_url)) { | 326 if (IsDefaultProfileImageURL(image_url)) { |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 384 // Callback for OAuth2TokenService::Request on failure. | 400 // Callback for OAuth2TokenService::Request on failure. |
| 385 void ProfileDownloader::OnGetTokenFailure( | 401 void ProfileDownloader::OnGetTokenFailure( |
| 386 const OAuth2TokenService::Request* request, | 402 const OAuth2TokenService::Request* request, |
| 387 const GoogleServiceAuthError& error) { | 403 const GoogleServiceAuthError& error) { |
| 388 DCHECK_EQ(request, oauth2_access_token_request_.get()); | 404 DCHECK_EQ(request, oauth2_access_token_request_.get()); |
| 389 oauth2_access_token_request_.reset(); | 405 oauth2_access_token_request_.reset(); |
| 390 LOG(WARNING) << "ProfileDownloader: token request using refresh token failed"; | 406 LOG(WARNING) << "ProfileDownloader: token request using refresh token failed"; |
| 391 delegate_->OnProfileDownloadFailure( | 407 delegate_->OnProfileDownloadFailure( |
| 392 this, ProfileDownloaderDelegate::TOKEN_ERROR); | 408 this, ProfileDownloaderDelegate::TOKEN_ERROR); |
| 393 } | 409 } |
| OLD | NEW |