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

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: review #15 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 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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 if (retry_count_ >= kMaxRetryLanguageListFetcher) {
207 NotifyEvent(__LINE__, "Request is omitted due to retry limit");
208 return false;
209 }
210 retry_count_++;
211
202 state_ = REQUESTING; 212 state_ = REQUESTING;
203 callback_ = callback; 213 callback_ = callback;
204 214
205 GURL url = GURL(kLanguageListFetchURL); 215 GURL url = GURL(kLanguageListFetchURL);
206 url = TranslateURLUtil::AddHostLocaleToUrl(url); 216 url = TranslateURLUtil::AddHostLocaleToUrl(url);
207 url = TranslateURLUtil::AddApiKeyToUrl(url); 217 url = TranslateURLUtil::AddApiKeyToUrl(url);
208 if (include_alpha_languages_) { 218 if (include_alpha_languages_) {
209 url = net::AppendQueryParameter(url, 219 url = net::AppendQueryParameter(url,
210 kAlphaLanguageQueryName, 220 kAlphaLanguageQueryName,
211 kAlphaLanguageQueryValue); 221 kAlphaLanguageQueryValue);
212 } 222 }
213 223
214 std::string message = base::StringPrintf( 224 std::string message = base::StringPrintf(
215 "%s list fetch starts (URL: %s)", 225 "%s list fetch starts (URL: %s)",
216 include_alpha_languages_ ? "Language" : "Alpha language", 226 include_alpha_languages_ ? "Language" : "Alpha language",
217 url.spec().c_str()); 227 url.spec().c_str());
218 NotifyEvent(__LINE__, message); 228 NotifyEvent(__LINE__, message);
219 229
220 fetcher_.reset(net::URLFetcher::Create( 230 fetcher_.reset(net::URLFetcher::Create(
221 include_alpha_languages_ ? kFetcherIdForAlphaLanguageList : 231 include_alpha_languages_ ? kFetcherIdForAlphaLanguageList :
222 kFetcherIdForLanguageList, 232 kFetcherIdForLanguageList,
223 url, 233 url,
224 net::URLFetcher::GET, 234 net::URLFetcher::GET,
225 this)); 235 this));
226 fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES | 236 fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES |
227 net::LOAD_DO_NOT_SAVE_COOKIES); 237 net::LOAD_DO_NOT_SAVE_COOKIES);
228 fetcher_->SetRequestContext(g_browser_process->system_request_context()); 238 fetcher_->SetRequestContext(g_browser_process->system_request_context());
229 fetcher_->SetMaxRetriesOn5xx(kMaxRetryLanguageListFetch); 239 // Set retry parameter for HTTP status code 5xx. This doesn't work against
240 // 106 (net::ERR_INTERNET_DISCONNECTED) and so on.
241 // TranslateLanguageList handles network status, and implements retry.
242 fetcher_->SetMaxRetriesOn5xx(kMaxRetryLanguageListFetchOn5xx);
230 fetcher_->Start(); 243 fetcher_->Start();
231 244
232 return true; 245 return true;
233 } 246 }
234 247
235 void TranslateLanguageList::LanguageListFetcher::OnURLFetchComplete( 248 void TranslateLanguageList::LanguageListFetcher::OnURLFetchComplete(
236 const net::URLFetcher* source) { 249 const net::URLFetcher* source) {
237 DCHECK(fetcher_.get() == source); 250 DCHECK(fetcher_.get() == source);
238 251
239 std::string data; 252 std::string data;
240 if (source->GetStatus().status() == net::URLRequestStatus::SUCCESS && 253 if (source->GetStatus().status() == net::URLRequestStatus::SUCCESS &&
241 source->GetResponseCode() == net::HTTP_OK) { 254 source->GetResponseCode() == net::HTTP_OK) {
242 state_ = COMPLETED; 255 state_ = COMPLETED;
243 source->GetResponseAsString(&data); 256 source->GetResponseAsString(&data);
244 std::string message = base::StringPrintf( 257 std::string message = base::StringPrintf(
245 "%s list is updated", 258 "%s list is updated",
246 include_alpha_languages_ ? "Alpha language" : "Language"); 259 include_alpha_languages_ ? "Alpha language" : "Language");
247 NotifyEvent(__LINE__, message); 260 NotifyEvent(__LINE__, message);
248 } else { 261 } else {
249 state_ = FAILED; 262 state_ = FAILED;
250 std::string message = base::StringPrintf( 263 std::string message = base::StringPrintf(
251 "Failed to Fetch languages from: %s", 264 "Failed to Fetch languages from: %s",
252 source->GetURL().spec().c_str()); 265 source->GetURL().spec().c_str());
253 NotifyEvent(__LINE__, message); 266 NotifyEvent(__LINE__, message);
254 } 267 }
255 268
269 // Transfer URLFetcher's ownership before invoking a callback.
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
260 // This must be kept in sync with the &cb= value in the kLanguageListFetchURL. 274 // This must be kept in sync with the &cb= value in the kLanguageListFetchURL.
261 const char TranslateLanguageList::kLanguageListCallbackName[] = "sl("; 275 const char TranslateLanguageList::kLanguageListCallbackName[] = "sl(";
262 const char TranslateLanguageList::kTargetLanguagesKey[] = "tl"; 276 const char TranslateLanguageList::kTargetLanguagesKey[] = "tl";
263 277
264 TranslateLanguageList::TranslateLanguageList() { 278 TranslateLanguageList::TranslateLanguageList() {
265 // We default to our hard coded list of languages in 279 // We default to our hard coded list of languages in
266 // |kDefaultSupportedLanguages|. This list will be overriden by a server 280 // |kDefaultSupportedLanguages|. This list will be overriden by a server
267 // providing supported langauges list. 281 // providing supported langauges list.
268 for (size_t i = 0; i < arraysize(kDefaultSupportedLanguages); ++i) 282 for (size_t i = 0; i < arraysize(kDefaultSupportedLanguages); ++i)
269 supported_languages_.insert(kDefaultSupportedLanguages[i]); 283 supported_languages_.insert(kDefaultSupportedLanguages[i]);
270 UpdateSupportedLanguages(); 284 UpdateSupportedLanguages();
271 285
272 language_list_fetcher_.reset(new LanguageListFetcher(false)); 286 language_list_fetcher_.reset(new LanguageListFetcher(false));
273 alpha_language_list_fetcher_.reset(new LanguageListFetcher(true)); 287 alpha_language_list_fetcher_.reset(new LanguageListFetcher(true));
288
289 resource_request_allowed_notifier_.Init(this);
274 } 290 }
275 291
276 TranslateLanguageList::~TranslateLanguageList() { 292 TranslateLanguageList::~TranslateLanguageList() {
277 } 293 }
278 294
279 void TranslateLanguageList::GetSupportedLanguages( 295 void TranslateLanguageList::GetSupportedLanguages(
280 std::vector<std::string>* languages) { 296 std::vector<std::string>* languages) {
281 DCHECK(languages && languages->empty()); 297 DCHECK(languages && languages->empty());
282 std::set<std::string>::const_iterator iter = all_supported_languages_.begin(); 298 std::set<std::string>::const_iterator iter = all_supported_languages_.begin();
283 for (; iter != all_supported_languages_.end(); ++iter) 299 for (; iter != all_supported_languages_.end(); ++iter)
284 languages->push_back(*iter); 300 languages->push_back(*iter);
301
302 // Update language lists if they are not updated after Chrome was launched
303 // for later requests.
304 if (language_list_fetcher_.get() || alpha_language_list_fetcher_.get())
305 RequestLanguageList();
285 } 306 }
286 307
287 std::string TranslateLanguageList::GetLanguageCode( 308 std::string TranslateLanguageList::GetLanguageCode(
288 const std::string& chrome_locale) { 309 const std::string& chrome_locale) {
289 // Only remove the country code for country specific languages we don't 310 // Only remove the country code for country specific languages we don't
290 // support specifically yet. 311 // support specifically yet.
291 if (IsSupportedLanguage(chrome_locale)) 312 if (IsSupportedLanguage(chrome_locale))
292 return chrome_locale; 313 return chrome_locale;
293 314
294 size_t hypen_index = chrome_locale.find('-'); 315 size_t hypen_index = chrome_locale.find('-');
295 if (hypen_index == std::string::npos) 316 if (hypen_index == std::string::npos)
296 return chrome_locale; 317 return chrome_locale;
297 return chrome_locale.substr(0, hypen_index); 318 return chrome_locale.substr(0, hypen_index);
298 } 319 }
299 320
300 bool TranslateLanguageList::IsSupportedLanguage(const std::string& language) { 321 bool TranslateLanguageList::IsSupportedLanguage(const std::string& language) {
301 return all_supported_languages_.count(language) != 0; 322 return all_supported_languages_.count(language) != 0;
302 } 323 }
303 324
304 bool TranslateLanguageList::IsAlphaLanguage(const std::string& language) { 325 bool TranslateLanguageList::IsAlphaLanguage(const std::string& language) {
305 // |language| should exist only in the alpha language list. 326 // |language| should exist only in the alpha language list.
306 return supported_alpha_languages_.count(language) != 0 && 327 return supported_alpha_languages_.count(language) != 0 &&
307 supported_languages_.count(language) == 0; 328 supported_languages_.count(language) == 0;
308 } 329 }
309 330
310 void TranslateLanguageList::RequestLanguageList() { 331 void TranslateLanguageList::RequestLanguageList() {
332 // If resource requests are not allowed, we'll get a callback when they are.
333 if (resource_request_allowed_notifier_.ResourceRequestsAllowed())
334 OnResourceRequestsAllowed();
335 }
336
337 void TranslateLanguageList::OnResourceRequestsAllowed() {
311 if (language_list_fetcher_.get() && 338 if (language_list_fetcher_.get() &&
312 (language_list_fetcher_->state() == LanguageListFetcher::IDLE || 339 (language_list_fetcher_->state() == LanguageListFetcher::IDLE ||
313 language_list_fetcher_->state() == LanguageListFetcher::FAILED)) { 340 language_list_fetcher_->state() == LanguageListFetcher::FAILED)) {
314 language_list_fetcher_->Request( 341 language_list_fetcher_->Request(
315 base::Bind(&TranslateLanguageList::OnLanguageListFetchComplete, 342 base::Bind(&TranslateLanguageList::OnLanguageListFetchComplete,
316 base::Unretained(this))); 343 base::Unretained(this)));
317 } 344 }
318 345
319 if (alpha_language_list_fetcher_.get() && 346 if (alpha_language_list_fetcher_.get() &&
320 (alpha_language_list_fetcher_->state() == LanguageListFetcher::IDLE || 347 (alpha_language_list_fetcher_->state() == LanguageListFetcher::IDLE ||
321 alpha_language_list_fetcher_->state() == LanguageListFetcher::FAILED)) { 348 alpha_language_list_fetcher_->state() == LanguageListFetcher::FAILED)) {
322 alpha_language_list_fetcher_->Request( 349 alpha_language_list_fetcher_->Request(
323 base::Bind(&TranslateLanguageList::OnLanguageListFetchComplete, 350 base::Bind(&TranslateLanguageList::OnLanguageListFetchComplete,
324 base::Unretained(this))); 351 base::Unretained(this)));
325 } 352 }
326 } 353 }
327 354
328 void TranslateLanguageList::OnLanguageListFetchComplete( 355 void TranslateLanguageList::OnLanguageListFetchComplete(
329 bool include_alpha_languages, 356 bool include_alpha_languages,
330 bool success, 357 bool success,
331 const std::string& data) { 358 const std::string& data) {
332 if (!success) 359 if (!success) {
360 resource_request_allowed_notifier_.ResourceRequestsAllowed();
361 // Since it fails just now, omit to schedule resource requests if
362 // ResourceRequestAllowedNotifier think it's ready. Otherwise, a callback
363 // will be invoked later to reuest resources again.
364 // The LanguageListFetcher has a limit |kMaxRetryLanguageListFetcher| and
365 // aborts re-try not to invoke OnLanguageListFetchComplete anymore if it's
366 // asked to re-try too many times.
367 to invoke OnLanguageListFetchComplete.
Alexei Svitkine (slow) 2013/06/14 22:06:05 Nit: remove this line?
Takashi Toyoshima 2013/06/17 07:20:04 Sorry for poor nit... Removed.
333 return; 368 return;
369 }
334 370
335 if (!include_alpha_languages) { 371 if (!include_alpha_languages) {
336 SetSupportedLanguages(data, &supported_languages_); 372 SetSupportedLanguages(data, &supported_languages_);
337 language_list_fetcher_.reset(); 373 language_list_fetcher_.reset();
338 } else { 374 } else {
339 SetSupportedLanguages(data, &supported_alpha_languages_); 375 SetSupportedLanguages(data, &supported_alpha_languages_);
340 alpha_language_list_fetcher_.reset(); 376 alpha_language_list_fetcher_.reset();
341 } 377 }
342 UpdateSupportedLanguages(); 378 UpdateSupportedLanguages();
343 } 379 }
344 380
345 void TranslateLanguageList::UpdateSupportedLanguages() { 381 void TranslateLanguageList::UpdateSupportedLanguages() {
346 all_supported_languages_.clear(); 382 all_supported_languages_.clear();
347 std::set<std::string>::const_iterator iter; 383 std::set<std::string>::const_iterator iter;
348 for (iter = supported_languages_.begin(); 384 for (iter = supported_languages_.begin();
349 iter != supported_languages_.end(); 385 iter != supported_languages_.end();
350 ++iter) 386 ++iter)
351 all_supported_languages_.insert(*iter); 387 all_supported_languages_.insert(*iter);
352 for (iter = supported_alpha_languages_.begin(); 388 for (iter = supported_alpha_languages_.begin();
353 iter != supported_alpha_languages_.end(); 389 iter != supported_alpha_languages_.end();
354 ++iter) 390 ++iter)
355 all_supported_languages_.insert(*iter); 391 all_supported_languages_.insert(*iter);
356 } 392 }
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