Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 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/translate/translate_language_list.h" | 5 #include "chrome/browser/translate/translate_language_list.h" |
| 6 | 6 |
| 7 #include <set> | 7 #include <set> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/json/json_reader.h" | 10 #include "base/json/json_reader.h" |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 98 // Constant URL string to fetch server supporting language list. | 98 // Constant URL string to fetch server supporting language list. |
| 99 const char kLanguageListFetchURL[] = | 99 const char kLanguageListFetchURL[] = |
| 100 "https://translate.googleapis.com/translate_a/l?client=chrome&cb=sl"; | 100 "https://translate.googleapis.com/translate_a/l?client=chrome&cb=sl"; |
| 101 | 101 |
| 102 // Used in kTranslateScriptURL to request supporting languages list including | 102 // Used in kTranslateScriptURL to request supporting languages list including |
| 103 // "alpha languages". | 103 // "alpha languages". |
| 104 const char kAlphaLanguageQueryName[] = "alpha"; | 104 const char kAlphaLanguageQueryName[] = "alpha"; |
| 105 const char kAlphaLanguageQueryValue[] = "1"; | 105 const char kAlphaLanguageQueryValue[] = "1"; |
| 106 | 106 |
| 107 // Retry parameter for fetching supporting language list. | 107 // Retry parameter for fetching supporting language list. |
| 108 const int kMaxRetryLanguageListFetch = 5; | 108 const int kMaxRetryLanguageListFetchOn5xx = 5; |
| 109 | |
| 110 // Retry parameter for LanguageListFetcher. | |
| 111 const int kMaxRetryLanguageListFetcher = 16; | |
| 109 | 112 |
| 110 // Assign following IDs to URLFetchers so that tests can distinguish each | 113 // Assign following IDs to URLFetchers so that tests can distinguish each |
| 111 // request in order to simiulate respectively. | 114 // request in order to simiulate respectively. |
| 112 const int kFetcherIdForLanguageList = 1; | 115 const int kFetcherIdForLanguageList = 1; |
| 113 const int kFetcherIdForAlphaLanguageList = 2; | 116 const int kFetcherIdForAlphaLanguageList = 2; |
| 114 | 117 |
| 115 // Show a message in chrome:://translate-internals Event Logs. | 118 // Show a message in chrome:://translate-internals Event Logs. |
| 116 void NotifyEvent(int line, const std::string& message) { | 119 void NotifyEvent(int line, const std::string& message) { |
| 117 TranslateManager* manager = TranslateManager::GetInstance(); | 120 TranslateManager* manager = TranslateManager::GetInstance(); |
| 118 DCHECK(manager); | 121 DCHECK(manager); |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 177 message += ", " + iter.key(); | 180 message += ", " + iter.key(); |
| 178 } | 181 } |
| 179 NotifyEvent(__LINE__, message); | 182 NotifyEvent(__LINE__, message); |
| 180 } | 183 } |
| 181 | 184 |
| 182 } // namespace | 185 } // namespace |
| 183 | 186 |
| 184 TranslateLanguageList::LanguageListFetcher::LanguageListFetcher( | 187 TranslateLanguageList::LanguageListFetcher::LanguageListFetcher( |
| 185 bool include_alpha_languages) | 188 bool include_alpha_languages) |
| 186 : include_alpha_languages_(include_alpha_languages), | 189 : include_alpha_languages_(include_alpha_languages), |
| 187 state_(IDLE) { | 190 state_(IDLE), |
| 191 retry_count_(0) { | |
| 188 } | 192 } |
| 189 | 193 |
| 190 TranslateLanguageList::LanguageListFetcher::~LanguageListFetcher() { | 194 TranslateLanguageList::LanguageListFetcher::~LanguageListFetcher() { |
| 191 } | 195 } |
| 192 | 196 |
| 193 bool TranslateLanguageList::LanguageListFetcher::Request( | 197 bool TranslateLanguageList::LanguageListFetcher::Request( |
| 194 const TranslateLanguageList::LanguageListFetcher::Callback& callback) { | 198 const TranslateLanguageList::LanguageListFetcher::Callback& callback) { |
| 195 // This function is not supporsed to be called before previous operaion is not | 199 // This function is not supposed to be called before previous operaion is not |
| 196 // finished. | 200 // finished. |
| 197 if (state_ == REQUESTING) { | 201 if (state_ == REQUESTING) { |
| 198 NOTREACHED(); | 202 NOTREACHED(); |
| 199 return false; | 203 return false; |
| 200 } | 204 } |
| 201 | 205 |
| 206 // Limits LanguageListFetcher level retry to kMaxRetryLanguageListFetcher | |
|
Alexei Svitkine (slow)
2013/06/13 14:46:02
Nit: I don't think the comment is needed, the code
Takashi Toyoshima
2013/06/14 09:10:48
Done.
| |
| 207 if (retry_count_ >= kMaxRetryLanguageListFetcher) { | |
| 208 NotifyEvent(__LINE__, "Request is omitted due to retry limitation"); | |
|
Alexei Svitkine (slow)
2013/06/13 14:46:02
Nit: limitation -> limit
(The two have slightly d
Takashi Toyoshima
2013/06/14 09:10:48
Wow, thank you:)
I didn't know.
Done!
| |
| 209 return false; | |
| 210 } | |
| 211 retry_count_++; | |
| 212 | |
| 202 state_ = REQUESTING; | 213 state_ = REQUESTING; |
| 203 callback_ = callback; | 214 callback_ = callback; |
| 204 | 215 |
| 205 GURL url = GURL(kLanguageListFetchURL); | 216 GURL url = GURL(kLanguageListFetchURL); |
| 206 url = TranslateURLUtil::AddHostLocaleToUrl(url); | 217 url = TranslateURLUtil::AddHostLocaleToUrl(url); |
| 207 url = TranslateURLUtil::AddApiKeyToUrl(url); | 218 url = TranslateURLUtil::AddApiKeyToUrl(url); |
| 208 if (include_alpha_languages_) { | 219 if (include_alpha_languages_) { |
| 209 url = net::AppendQueryParameter(url, | 220 url = net::AppendQueryParameter(url, |
| 210 kAlphaLanguageQueryName, | 221 kAlphaLanguageQueryName, |
| 211 kAlphaLanguageQueryValue); | 222 kAlphaLanguageQueryValue); |
| 212 } | 223 } |
| 213 | 224 |
| 214 std::string message = base::StringPrintf( | 225 std::string message = base::StringPrintf( |
| 215 "%s list fetch starts (URL: %s)", | 226 "%s list fetch starts (URL: %s)", |
| 216 include_alpha_languages_ ? "Language" : "Alpha language", | 227 include_alpha_languages_ ? "Language" : "Alpha language", |
| 217 url.spec().c_str()); | 228 url.spec().c_str()); |
| 218 NotifyEvent(__LINE__, message); | 229 NotifyEvent(__LINE__, message); |
| 219 | 230 |
| 220 fetcher_.reset(net::URLFetcher::Create( | 231 fetcher_.reset(net::URLFetcher::Create( |
| 221 include_alpha_languages_ ? kFetcherIdForAlphaLanguageList : | 232 include_alpha_languages_ ? kFetcherIdForAlphaLanguageList : |
| 222 kFetcherIdForLanguageList, | 233 kFetcherIdForLanguageList, |
| 223 url, | 234 url, |
| 224 net::URLFetcher::GET, | 235 net::URLFetcher::GET, |
| 225 this)); | 236 this)); |
| 226 fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES | | 237 fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES | |
| 227 net::LOAD_DO_NOT_SAVE_COOKIES); | 238 net::LOAD_DO_NOT_SAVE_COOKIES); |
| 228 fetcher_->SetRequestContext(g_browser_process->system_request_context()); | 239 fetcher_->SetRequestContext(g_browser_process->system_request_context()); |
| 229 fetcher_->SetMaxRetriesOn5xx(kMaxRetryLanguageListFetch); | 240 // Set retry parameter for HTTP status code 5xx. This doesn't work against |
| 241 // 106 (net::ERR_INTERNET_DISCONNECTED) and so on. | |
| 242 // TranslateLanguageList handles network status, and implements retry. | |
| 243 fetcher_->SetMaxRetriesOn5xx(kMaxRetryLanguageListFetchOn5xx); | |
| 230 fetcher_->Start(); | 244 fetcher_->Start(); |
| 231 | 245 |
| 232 return true; | 246 return true; |
| 233 } | 247 } |
| 234 | 248 |
| 235 void TranslateLanguageList::LanguageListFetcher::OnURLFetchComplete( | 249 void TranslateLanguageList::LanguageListFetcher::OnURLFetchComplete( |
| 236 const net::URLFetcher* source) { | 250 const net::URLFetcher* source) { |
| 237 DCHECK(fetcher_.get() == source); | 251 DCHECK(fetcher_.get() == source); |
| 238 | 252 |
| 239 std::string data; | 253 std::string data; |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 250 std::string message = base::StringPrintf( | 264 std::string message = base::StringPrintf( |
| 251 "Failed to Fetch languages from: %s", | 265 "Failed to Fetch languages from: %s", |
| 252 source->GetURL().spec().c_str()); | 266 source->GetURL().spec().c_str()); |
| 253 NotifyEvent(__LINE__, message); | 267 NotifyEvent(__LINE__, message); |
| 254 } | 268 } |
| 255 | 269 |
| 256 scoped_ptr<const net::URLFetcher> delete_ptr(fetcher_.release()); | 270 scoped_ptr<const net::URLFetcher> delete_ptr(fetcher_.release()); |
| 257 callback_.Run(include_alpha_languages_, state_ == COMPLETED, data); | 271 callback_.Run(include_alpha_languages_, state_ == COMPLETED, data); |
| 258 } | 272 } |
| 259 | 273 |
| 274 // Transfer URLFetcher's ownership before invoking a callback. | |
|
Alexei Svitkine (slow)
2013/06/13 14:46:02
This comment seems out of place...
Takashi Toyoshima
2013/06/14 09:10:48
Oops. Sorry, it looks like that I made wrong rebas
| |
| 260 // This must be kept in sync with the &cb= value in the kLanguageListFetchURL. | 275 // This must be kept in sync with the &cb= value in the kLanguageListFetchURL. |
| 261 const char TranslateLanguageList::kLanguageListCallbackName[] = "sl("; | 276 const char TranslateLanguageList::kLanguageListCallbackName[] = "sl("; |
| 262 const char TranslateLanguageList::kTargetLanguagesKey[] = "tl"; | 277 const char TranslateLanguageList::kTargetLanguagesKey[] = "tl"; |
| 263 | 278 |
| 264 TranslateLanguageList::TranslateLanguageList() { | 279 TranslateLanguageList::TranslateLanguageList() { |
| 265 // We default to our hard coded list of languages in | 280 // We default to our hard coded list of languages in |
| 266 // |kDefaultSupportedLanguages|. This list will be overriden by a server | 281 // |kDefaultSupportedLanguages|. This list will be overriden by a server |
| 267 // providing supported langauges list. | 282 // providing supported langauges list. |
| 268 for (size_t i = 0; i < arraysize(kDefaultSupportedLanguages); ++i) | 283 for (size_t i = 0; i < arraysize(kDefaultSupportedLanguages); ++i) |
| 269 supported_languages_.insert(kDefaultSupportedLanguages[i]); | 284 supported_languages_.insert(kDefaultSupportedLanguages[i]); |
| 270 UpdateSupportedLanguages(); | 285 UpdateSupportedLanguages(); |
| 271 | 286 |
| 272 language_list_fetcher_.reset(new LanguageListFetcher(false)); | 287 language_list_fetcher_.reset(new LanguageListFetcher(false)); |
| 273 alpha_language_list_fetcher_.reset(new LanguageListFetcher(true)); | 288 alpha_language_list_fetcher_.reset(new LanguageListFetcher(true)); |
| 289 | |
| 290 resource_request_allowed_notifier_.Init(this); | |
| 274 } | 291 } |
| 275 | 292 |
| 276 TranslateLanguageList::~TranslateLanguageList() { | 293 TranslateLanguageList::~TranslateLanguageList() { |
| 277 } | 294 } |
| 278 | 295 |
| 279 void TranslateLanguageList::GetSupportedLanguages( | 296 void TranslateLanguageList::GetSupportedLanguages( |
| 280 std::vector<std::string>* languages) { | 297 std::vector<std::string>* languages) { |
| 281 DCHECK(languages && languages->empty()); | 298 DCHECK(languages && languages->empty()); |
| 282 std::set<std::string>::const_iterator iter = all_supported_languages_.begin(); | 299 std::set<std::string>::const_iterator iter = all_supported_languages_.begin(); |
| 283 for (; iter != all_supported_languages_.end(); ++iter) | 300 for (; iter != all_supported_languages_.end(); ++iter) |
| 284 languages->push_back(*iter); | 301 languages->push_back(*iter); |
| 302 | |
| 303 // Update language lists if they are not updated after Chrome was launched | |
| 304 // for later requests. | |
| 305 if (language_list_fetcher_.get() || alpha_language_list_fetcher_.get()) | |
| 306 RequestLanguageList(); | |
| 285 } | 307 } |
| 286 | 308 |
| 287 std::string TranslateLanguageList::GetLanguageCode( | 309 std::string TranslateLanguageList::GetLanguageCode( |
| 288 const std::string& chrome_locale) { | 310 const std::string& chrome_locale) { |
| 289 // Only remove the country code for country specific languages we don't | 311 // Only remove the country code for country specific languages we don't |
| 290 // support specifically yet. | 312 // support specifically yet. |
| 291 if (IsSupportedLanguage(chrome_locale)) | 313 if (IsSupportedLanguage(chrome_locale)) |
| 292 return chrome_locale; | 314 return chrome_locale; |
| 293 | 315 |
| 294 size_t hypen_index = chrome_locale.find('-'); | 316 size_t hypen_index = chrome_locale.find('-'); |
| 295 if (hypen_index == std::string::npos) | 317 if (hypen_index == std::string::npos) |
| 296 return chrome_locale; | 318 return chrome_locale; |
| 297 return chrome_locale.substr(0, hypen_index); | 319 return chrome_locale.substr(0, hypen_index); |
| 298 } | 320 } |
| 299 | 321 |
| 300 bool TranslateLanguageList::IsSupportedLanguage(const std::string& language) { | 322 bool TranslateLanguageList::IsSupportedLanguage(const std::string& language) { |
| 301 return all_supported_languages_.count(language) != 0; | 323 return all_supported_languages_.count(language) != 0; |
| 302 } | 324 } |
| 303 | 325 |
| 304 bool TranslateLanguageList::IsAlphaLanguage(const std::string& language) { | 326 bool TranslateLanguageList::IsAlphaLanguage(const std::string& language) { |
| 305 // |language| should exist only in the alpha language list. | 327 // |language| should exist only in the alpha language list. |
| 306 return supported_alpha_languages_.count(language) != 0 && | 328 return supported_alpha_languages_.count(language) != 0 && |
| 307 supported_languages_.count(language) == 0; | 329 supported_languages_.count(language) == 0; |
| 308 } | 330 } |
| 309 | 331 |
| 310 void TranslateLanguageList::RequestLanguageList() { | 332 void TranslateLanguageList::RequestLanguageList() { |
| 333 // If resource requests are not allowed, we'll get a callback when they are. | |
| 334 if (resource_request_allowed_notifier_.ResourceRequestsAllowed()) | |
| 335 OnResourceRequestsAllowed(); | |
| 336 } | |
| 337 | |
| 338 void TranslateLanguageList::OnResourceRequestsAllowed() { | |
| 311 if (language_list_fetcher_.get() && | 339 if (language_list_fetcher_.get() && |
| 312 (language_list_fetcher_->state() == LanguageListFetcher::IDLE || | 340 (language_list_fetcher_->state() == LanguageListFetcher::IDLE || |
| 313 language_list_fetcher_->state() == LanguageListFetcher::FAILED)) { | 341 language_list_fetcher_->state() == LanguageListFetcher::FAILED)) { |
| 314 language_list_fetcher_->Request( | 342 language_list_fetcher_->Request( |
| 315 base::Bind(&TranslateLanguageList::OnLanguageListFetchComplete, | 343 base::Bind(&TranslateLanguageList::OnLanguageListFetchComplete, |
| 316 base::Unretained(this))); | 344 base::Unretained(this))); |
| 317 } | 345 } |
| 318 | 346 |
| 319 if (alpha_language_list_fetcher_.get() && | 347 if (alpha_language_list_fetcher_.get() && |
| 320 (alpha_language_list_fetcher_->state() == LanguageListFetcher::IDLE || | 348 (alpha_language_list_fetcher_->state() == LanguageListFetcher::IDLE || |
| 321 alpha_language_list_fetcher_->state() == LanguageListFetcher::FAILED)) { | 349 alpha_language_list_fetcher_->state() == LanguageListFetcher::FAILED)) { |
| 322 alpha_language_list_fetcher_->Request( | 350 alpha_language_list_fetcher_->Request( |
| 323 base::Bind(&TranslateLanguageList::OnLanguageListFetchComplete, | 351 base::Bind(&TranslateLanguageList::OnLanguageListFetchComplete, |
| 324 base::Unretained(this))); | 352 base::Unretained(this))); |
| 325 } | 353 } |
| 326 } | 354 } |
| 327 | 355 |
| 328 void TranslateLanguageList::OnLanguageListFetchComplete( | 356 void TranslateLanguageList::OnLanguageListFetchComplete( |
| 329 bool include_alpha_languages, | 357 bool include_alpha_languages, |
| 330 bool success, | 358 bool success, |
| 331 const std::string& data) { | 359 const std::string& data) { |
| 332 if (!success) | 360 if (!success) { |
| 361 resource_request_allowed_notifier_.ResourceRequestsAllowed(); | |
| 362 // Since it fails just now, omit to schedule resource requests if | |
| 363 // ResourceRequestAllowedNotifier think it's ready. Otherwise, a callback | |
| 364 // will be invoked later to reuest resources again. | |
|
Alexei Svitkine (slow)
2013/06/13 14:46:02
Can you expand this comment to mention that fetche
Takashi Toyoshima
2013/06/14 09:10:48
Done.
| |
| 333 return; | 365 return; |
| 366 } | |
| 334 | 367 |
| 335 if (!include_alpha_languages) { | 368 if (!include_alpha_languages) { |
| 336 SetSupportedLanguages(data, &supported_languages_); | 369 SetSupportedLanguages(data, &supported_languages_); |
| 337 language_list_fetcher_.reset(); | 370 language_list_fetcher_.reset(); |
| 338 } else { | 371 } else { |
| 339 SetSupportedLanguages(data, &supported_alpha_languages_); | 372 SetSupportedLanguages(data, &supported_alpha_languages_); |
| 340 alpha_language_list_fetcher_.reset(); | 373 alpha_language_list_fetcher_.reset(); |
| 341 } | 374 } |
| 342 UpdateSupportedLanguages(); | 375 UpdateSupportedLanguages(); |
| 343 } | 376 } |
| 344 | 377 |
| 345 void TranslateLanguageList::UpdateSupportedLanguages() { | 378 void TranslateLanguageList::UpdateSupportedLanguages() { |
| 346 all_supported_languages_.clear(); | 379 all_supported_languages_.clear(); |
| 347 std::set<std::string>::const_iterator iter; | 380 std::set<std::string>::const_iterator iter; |
| 348 for (iter = supported_languages_.begin(); | 381 for (iter = supported_languages_.begin(); |
| 349 iter != supported_languages_.end(); | 382 iter != supported_languages_.end(); |
| 350 ++iter) | 383 ++iter) |
| 351 all_supported_languages_.insert(*iter); | 384 all_supported_languages_.insert(*iter); |
| 352 for (iter = supported_alpha_languages_.begin(); | 385 for (iter = supported_alpha_languages_.begin(); |
| 353 iter != supported_alpha_languages_.end(); | 386 iter != supported_alpha_languages_.end(); |
| 354 ++iter) | 387 ++iter) |
| 355 all_supported_languages_.insert(*iter); | 388 all_supported_languages_.insert(*iter); |
| 356 } | 389 } |
| OLD | NEW |