Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(184)

Side by Side Diff: chrome/browser/translate/translate_language_list.cc

Issue 15949022: Translate: language list smart updater (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: (rebase to 16841020) Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
100 // Constant URL string to fetch server supporting language list. 100 // Constant URL string to fetch server supporting language list.
101 const char kLanguageListFetchURL[] = 101 const char kLanguageListFetchURL[] =
102 "https://translate.googleapis.com/translate_a/l?client=chrome&cb=sl"; 102 "https://translate.googleapis.com/translate_a/l?client=chrome&cb=sl";
103 103
104 // Used in kTranslateScriptURL to request supporting languages list including 104 // Used in kTranslateScriptURL to request supporting languages list including
105 // "alpha languages". 105 // "alpha languages".
106 const char kAlphaLanguageQueryName[] = "alpha"; 106 const char kAlphaLanguageQueryName[] = "alpha";
107 const char kAlphaLanguageQueryValue[] = "1"; 107 const char kAlphaLanguageQueryValue[] = "1";
108 108
109 // Retry parameter for fetching supporting language list. 109 // Retry parameter for fetching supporting language list.
110 const int kMaxRetryLanguageListFetch = 5; 110 const int kMaxRetryLanguageListFetchOn5xx = 5;
111
112 // Retry parameter for LanguageListFetcher.
113 const int kMaxRetryLanguageListFetcher = 16;
111 114
112 // Assign following IDs to URLFetchers so that tests can distinguish each 115 // Assign following IDs to URLFetchers so that tests can distinguish each
113 // request in order to simiulate respectively. 116 // request in order to simiulate respectively.
114 const int kFetcherIdForLanguageList = 1; 117 const int kFetcherIdForLanguageList = 1;
115 const int kFetcherIdForAlphaLanguageList = 2; 118 const int kFetcherIdForAlphaLanguageList = 2;
116 119
117 // Show a message in chrome:://translate-internals Event Logs. 120 // Show a message in chrome:://translate-internals Event Logs.
118 void NotifyEvent(int line, const std::string& message) { 121 void NotifyEvent(int line, const std::string& message) {
119 TranslateManager* manager = TranslateManager::GetInstance(); 122 TranslateManager* manager = TranslateManager::GetInstance();
120 DCHECK(manager); 123 DCHECK(manager);
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
186 message += ", " + lang; 189 message += ", " + lang;
187 } 190 }
188 NotifyEvent(__LINE__, message); 191 NotifyEvent(__LINE__, message);
189 } 192 }
190 193
191 } // namespace 194 } // namespace
192 195
193 TranslateLanguageList::LanguageListFetcher::LanguageListFetcher( 196 TranslateLanguageList::LanguageListFetcher::LanguageListFetcher(
194 bool include_alpha_languages) 197 bool include_alpha_languages)
195 : include_alpha_languages_(include_alpha_languages), 198 : include_alpha_languages_(include_alpha_languages),
196 state_(IDLE) { 199 state_(IDLE),
200 retry_count_(0) {
197 } 201 }
198 202
199 TranslateLanguageList::LanguageListFetcher::~LanguageListFetcher() { 203 TranslateLanguageList::LanguageListFetcher::~LanguageListFetcher() {
200 } 204 }
201 205
202 bool TranslateLanguageList::LanguageListFetcher::Request( 206 bool TranslateLanguageList::LanguageListFetcher::Request(
203 const TranslateLanguageList::LanguageListFetcher::Callback& callback) { 207 const TranslateLanguageList::LanguageListFetcher::Callback& callback) {
204 // This function is not supporsed to be called before previous operaion is not 208 // This function is not supposed to be called before previous operaion is not
205 // finished. 209 // finished.
206 if (state_ == REQUESTING) { 210 if (state_ == REQUESTING) {
207 NOTREACHED(); 211 NOTREACHED();
208 return false; 212 return false;
209 } 213 }
210 214
215 if (retry_count_ >= kMaxRetryLanguageListFetcher) {
216 NotifyEvent(__LINE__, "Request is omitted due to retry limit");
217 return false;
218 }
219 retry_count_++;
220
211 state_ = REQUESTING; 221 state_ = REQUESTING;
212 callback_ = callback; 222 callback_ = callback;
213 223
214 GURL url = GURL(kLanguageListFetchURL); 224 GURL url = GURL(kLanguageListFetchURL);
215 url = TranslateURLUtil::AddHostLocaleToUrl(url); 225 url = TranslateURLUtil::AddHostLocaleToUrl(url);
216 url = TranslateURLUtil::AddApiKeyToUrl(url); 226 url = TranslateURLUtil::AddApiKeyToUrl(url);
217 if (include_alpha_languages_) { 227 if (include_alpha_languages_) {
218 url = net::AppendQueryParameter(url, 228 url = net::AppendQueryParameter(url,
219 kAlphaLanguageQueryName, 229 kAlphaLanguageQueryName,
220 kAlphaLanguageQueryValue); 230 kAlphaLanguageQueryValue);
221 } 231 }
222 232
223 std::string message = base::StringPrintf( 233 std::string message = base::StringPrintf(
224 "%s list fetch starts (URL: %s)", 234 "%s list fetch starts (URL: %s)",
225 include_alpha_languages_ ? "Language" : "Alpha language", 235 include_alpha_languages_ ? "Language" : "Alpha language",
226 url.spec().c_str()); 236 url.spec().c_str());
227 NotifyEvent(__LINE__, message); 237 NotifyEvent(__LINE__, message);
228 238
229 fetcher_.reset(net::URLFetcher::Create( 239 fetcher_.reset(net::URLFetcher::Create(
230 include_alpha_languages_ ? kFetcherIdForAlphaLanguageList : 240 include_alpha_languages_ ? kFetcherIdForAlphaLanguageList :
231 kFetcherIdForLanguageList, 241 kFetcherIdForLanguageList,
232 url, 242 url,
233 net::URLFetcher::GET, 243 net::URLFetcher::GET,
234 this)); 244 this));
235 fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES | 245 fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES |
236 net::LOAD_DO_NOT_SAVE_COOKIES); 246 net::LOAD_DO_NOT_SAVE_COOKIES);
237 fetcher_->SetRequestContext(g_browser_process->system_request_context()); 247 fetcher_->SetRequestContext(g_browser_process->system_request_context());
238 fetcher_->SetMaxRetriesOn5xx(kMaxRetryLanguageListFetch); 248 // Set retry parameter for HTTP status code 5xx. This doesn't work against
249 // 106 (net::ERR_INTERNET_DISCONNECTED) and so on.
250 // TranslateLanguageList handles network status, and implements retry.
251 fetcher_->SetMaxRetriesOn5xx(kMaxRetryLanguageListFetchOn5xx);
239 fetcher_->Start(); 252 fetcher_->Start();
240 253
241 return true; 254 return true;
242 } 255 }
243 256
244 void TranslateLanguageList::LanguageListFetcher::OnURLFetchComplete( 257 void TranslateLanguageList::LanguageListFetcher::OnURLFetchComplete(
245 const net::URLFetcher* source) { 258 const net::URLFetcher* source) {
246 DCHECK(fetcher_.get() == source); 259 DCHECK(fetcher_.get() == source);
247 260
248 std::string data; 261 std::string data;
249 if (source->GetStatus().status() == net::URLRequestStatus::SUCCESS && 262 if (source->GetStatus().status() == net::URLRequestStatus::SUCCESS &&
250 source->GetResponseCode() == net::HTTP_OK) { 263 source->GetResponseCode() == net::HTTP_OK) {
251 state_ = COMPLETED; 264 state_ = COMPLETED;
252 source->GetResponseAsString(&data); 265 source->GetResponseAsString(&data);
253 std::string message = base::StringPrintf( 266 std::string message = base::StringPrintf(
254 "%s list is updated", 267 "%s list is updated",
255 include_alpha_languages_ ? "Alpha language" : "Language"); 268 include_alpha_languages_ ? "Alpha language" : "Language");
256 NotifyEvent(__LINE__, message); 269 NotifyEvent(__LINE__, message);
257 } else { 270 } else {
258 state_ = FAILED; 271 state_ = FAILED;
259 std::string message = base::StringPrintf( 272 std::string message = base::StringPrintf(
260 "Failed to Fetch languages from: %s", 273 "Failed to Fetch languages from: %s",
261 source->GetURL().spec().c_str()); 274 source->GetURL().spec().c_str());
262 NotifyEvent(__LINE__, message); 275 NotifyEvent(__LINE__, message);
263 } 276 }
264 277
278 // Transfer URLFetcher's ownership before invoking a callback.
265 scoped_ptr<const net::URLFetcher> delete_ptr(fetcher_.release()); 279 scoped_ptr<const net::URLFetcher> delete_ptr(fetcher_.release());
266 callback_.Run(include_alpha_languages_, state_ == COMPLETED, data); 280 callback_.Run(include_alpha_languages_, state_ == COMPLETED, data);
267 } 281 }
268 282
269 // This must be kept in sync with the &cb= value in the kLanguageListFetchURL. 283 // This must be kept in sync with the &cb= value in the kLanguageListFetchURL.
270 const char TranslateLanguageList::kLanguageListCallbackName[] = "sl("; 284 const char TranslateLanguageList::kLanguageListCallbackName[] = "sl(";
271 const char TranslateLanguageList::kTargetLanguagesKey[] = "tl"; 285 const char TranslateLanguageList::kTargetLanguagesKey[] = "tl";
272 286
273 TranslateLanguageList::TranslateLanguageList() { 287 TranslateLanguageList::TranslateLanguageList() {
274 // We default to our hard coded list of languages in 288 // We default to our hard coded list of languages in
275 // |kDefaultSupportedLanguages|. This list will be overriden by a server 289 // |kDefaultSupportedLanguages|. This list will be overriden by a server
276 // providing supported langauges list. 290 // providing supported langauges list.
277 for (size_t i = 0; i < arraysize(kDefaultSupportedLanguages); ++i) 291 for (size_t i = 0; i < arraysize(kDefaultSupportedLanguages); ++i)
278 supported_languages_.insert(kDefaultSupportedLanguages[i]); 292 supported_languages_.insert(kDefaultSupportedLanguages[i]);
279 UpdateSupportedLanguages(); 293 UpdateSupportedLanguages();
280 294
281 language_list_fetcher_.reset(new LanguageListFetcher(false)); 295 language_list_fetcher_.reset(new LanguageListFetcher(false));
282 alpha_language_list_fetcher_.reset(new LanguageListFetcher(true)); 296 alpha_language_list_fetcher_.reset(new LanguageListFetcher(true));
297
298 resource_request_allowed_notifier_.Init(this);
283 } 299 }
284 300
285 TranslateLanguageList::~TranslateLanguageList() { 301 TranslateLanguageList::~TranslateLanguageList() {
286 } 302 }
287 303
288 void TranslateLanguageList::GetSupportedLanguages( 304 void TranslateLanguageList::GetSupportedLanguages(
289 std::vector<std::string>* languages) { 305 std::vector<std::string>* languages) {
290 DCHECK(languages && languages->empty()); 306 DCHECK(languages && languages->empty());
291 std::set<std::string>::const_iterator iter = all_supported_languages_.begin(); 307 std::set<std::string>::const_iterator iter = all_supported_languages_.begin();
292 for (; iter != all_supported_languages_.end(); ++iter) 308 for (; iter != all_supported_languages_.end(); ++iter)
293 languages->push_back(*iter); 309 languages->push_back(*iter);
310
311 // Update language lists if they are not updated after Chrome was launched
312 // for later requests.
313 if (language_list_fetcher_.get() || alpha_language_list_fetcher_.get())
314 RequestLanguageList();
294 } 315 }
295 316
296 std::string TranslateLanguageList::GetLanguageCode( 317 std::string TranslateLanguageList::GetLanguageCode(
297 const std::string& chrome_locale) { 318 const std::string& chrome_locale) {
298 // Only remove the country code for country specific languages we don't 319 // Only remove the country code for country specific languages we don't
299 // support specifically yet. 320 // support specifically yet.
300 if (IsSupportedLanguage(chrome_locale)) 321 if (IsSupportedLanguage(chrome_locale))
301 return chrome_locale; 322 return chrome_locale;
302 323
303 size_t hypen_index = chrome_locale.find('-'); 324 size_t hypen_index = chrome_locale.find('-');
304 if (hypen_index == std::string::npos) 325 if (hypen_index == std::string::npos)
305 return chrome_locale; 326 return chrome_locale;
306 return chrome_locale.substr(0, hypen_index); 327 return chrome_locale.substr(0, hypen_index);
307 } 328 }
308 329
309 bool TranslateLanguageList::IsSupportedLanguage(const std::string& language) { 330 bool TranslateLanguageList::IsSupportedLanguage(const std::string& language) {
310 return all_supported_languages_.count(language) != 0; 331 return all_supported_languages_.count(language) != 0;
311 } 332 }
312 333
313 bool TranslateLanguageList::IsAlphaLanguage(const std::string& language) { 334 bool TranslateLanguageList::IsAlphaLanguage(const std::string& language) {
314 // |language| should exist only in the alpha language list. 335 // |language| should exist only in the alpha language list.
315 return supported_alpha_languages_.count(language) != 0 && 336 return supported_alpha_languages_.count(language) != 0 &&
316 supported_languages_.count(language) == 0; 337 supported_languages_.count(language) == 0;
317 } 338 }
318 339
319 void TranslateLanguageList::RequestLanguageList() { 340 void TranslateLanguageList::RequestLanguageList() {
341 // If resource requests are not allowed, we'll get a callback when they are.
342 if (resource_request_allowed_notifier_.ResourceRequestsAllowed())
343 OnResourceRequestsAllowed();
344 }
345
346 void TranslateLanguageList::OnResourceRequestsAllowed() {
320 if (language_list_fetcher_.get() && 347 if (language_list_fetcher_.get() &&
321 (language_list_fetcher_->state() == LanguageListFetcher::IDLE || 348 (language_list_fetcher_->state() == LanguageListFetcher::IDLE ||
322 language_list_fetcher_->state() == LanguageListFetcher::FAILED)) { 349 language_list_fetcher_->state() == LanguageListFetcher::FAILED)) {
323 language_list_fetcher_->Request( 350 language_list_fetcher_->Request(
324 base::Bind(&TranslateLanguageList::OnLanguageListFetchComplete, 351 base::Bind(&TranslateLanguageList::OnLanguageListFetchComplete,
325 base::Unretained(this))); 352 base::Unretained(this)));
326 } 353 }
327 354
328 if (alpha_language_list_fetcher_.get() && 355 if (alpha_language_list_fetcher_.get() &&
329 (alpha_language_list_fetcher_->state() == LanguageListFetcher::IDLE || 356 (alpha_language_list_fetcher_->state() == LanguageListFetcher::IDLE ||
330 alpha_language_list_fetcher_->state() == LanguageListFetcher::FAILED)) { 357 alpha_language_list_fetcher_->state() == LanguageListFetcher::FAILED)) {
331 alpha_language_list_fetcher_->Request( 358 alpha_language_list_fetcher_->Request(
332 base::Bind(&TranslateLanguageList::OnLanguageListFetchComplete, 359 base::Bind(&TranslateLanguageList::OnLanguageListFetchComplete,
333 base::Unretained(this))); 360 base::Unretained(this)));
334 } 361 }
335 } 362 }
336 363
337 void TranslateLanguageList::OnLanguageListFetchComplete( 364 void TranslateLanguageList::OnLanguageListFetchComplete(
338 bool include_alpha_languages, 365 bool include_alpha_languages,
339 bool success, 366 bool success,
340 const std::string& data) { 367 const std::string& data) {
341 if (!success) 368 if (!success) {
369 resource_request_allowed_notifier_.ResourceRequestsAllowed();
370 // Since it fails just now, omit to schedule resource requests if
371 // ResourceRequestAllowedNotifier think it's ready. Otherwise, a callback
372 // will be invoked later to reuest resources again.
MAD 2013/06/17 14:48:41 reuest -> request?
Takashi Toyoshima 2013/06/19 10:06:15 Done.
373 // The LanguageListFetcher has a limit |kMaxRetryLanguageListFetcher| and
374 // aborts re-try not to invoke OnLanguageListFetchComplete anymore if it's
375 // asked to re-try too many times.
342 return; 376 return;
377 }
343 378
344 if (!include_alpha_languages) { 379 if (!include_alpha_languages) {
345 SetSupportedLanguages(data, &supported_languages_); 380 SetSupportedLanguages(data, &supported_languages_);
346 language_list_fetcher_.reset(); 381 language_list_fetcher_.reset();
347 } else { 382 } else {
348 SetSupportedLanguages(data, &supported_alpha_languages_); 383 SetSupportedLanguages(data, &supported_alpha_languages_);
349 alpha_language_list_fetcher_.reset(); 384 alpha_language_list_fetcher_.reset();
350 } 385 }
351 UpdateSupportedLanguages(); 386 UpdateSupportedLanguages();
352 387
353 last_updated_ = base::Time::Now(); 388 last_updated_ = base::Time::Now();
354 } 389 }
355 390
356 void TranslateLanguageList::UpdateSupportedLanguages() { 391 void TranslateLanguageList::UpdateSupportedLanguages() {
357 all_supported_languages_.clear(); 392 all_supported_languages_.clear();
358 std::set<std::string>::const_iterator iter; 393 std::set<std::string>::const_iterator iter;
359 for (iter = supported_languages_.begin(); 394 for (iter = supported_languages_.begin();
360 iter != supported_languages_.end(); 395 iter != supported_languages_.end();
361 ++iter) { 396 ++iter) {
362 all_supported_languages_.insert(*iter); 397 all_supported_languages_.insert(*iter);
363 } 398 }
364 for (iter = supported_alpha_languages_.begin(); 399 for (iter = supported_alpha_languages_.begin();
365 iter != supported_alpha_languages_.end(); 400 iter != supported_alpha_languages_.end();
366 ++iter) { 401 ++iter) {
367 all_supported_languages_.insert(*iter); 402 all_supported_languages_.insert(*iter);
368 } 403 }
369 } 404 }
OLDNEW
« no previous file with comments | « chrome/browser/translate/translate_language_list.h ('k') | chrome/browser/translate/translate_manager_browsertest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698