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

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: done 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/json/json_reader.h" 10 #include "base/json/json_reader.h"
10 #include "base/lazy_instance.h" 11 #include "base/lazy_instance.h"
11 #include "base/logging.h" 12 #include "base/logging.h"
12 #include "base/string_util.h" 13 #include "base/string_util.h"
13 #include "base/values.h" 14 #include "base/values.h"
14 #include "chrome/browser/browser_process.h" 15 #include "chrome/browser/browser_process.h"
15 #include "chrome/browser/translate/translate_url_util.h" 16 #include "chrome/browser/translate/translate_url_util.h"
16 #include "googleurl/src/gurl.h" 17 #include "googleurl/src/gurl.h"
17 #include "net/base/load_flags.h" 18 #include "net/base/load_flags.h"
18 #include "net/base/url_util.h" 19 #include "net/base/url_util.h"
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
148 set->clear(); 149 set->clear();
149 // ... and replace it with the values we just fetched from the server. 150 // ... and replace it with the values we just fetched from the server.
150 for (DictionaryValue::Iterator iter(*target_languages); 151 for (DictionaryValue::Iterator iter(*target_languages);
151 !iter.IsAtEnd(); 152 !iter.IsAtEnd();
152 iter.Advance()) { 153 iter.Advance()) {
153 // TODO(toyoshim): Check if UI libraries support adding locale. 154 // TODO(toyoshim): Check if UI libraries support adding locale.
154 set->insert(iter.key()); 155 set->insert(iter.key());
155 } 156 }
156 } 157 }
157 158
158 net::URLFetcher* CreateAndStartFetch(int id, 159 } // namespace
159 const GURL& url, 160
160 net::URLFetcherDelegate* delegate) { 161 TranslateLanguageList::LanguageListFetcher::LanguageListFetcher(
161 DCHECK(delegate); 162 bool include_alpha_languages)
163 : include_alpha_languages_(include_alpha_languages),
164 state_(IDLE) {
165 }
166
167 TranslateLanguageList::LanguageListFetcher::~LanguageListFetcher() {
168 }
169
170 void TranslateLanguageList::LanguageListFetcher::Request(
171 const TranslateLanguageList::LanguageListFetcher::Callback& callback) {
172 if (state_ == REQUESTING) {
173 callback.Run(include_alpha_languages_, false, std::string());
MAD 2013/06/07 13:29:24 If callbacks are comparable, shouldn't we simply D
Takashi Toyoshima 2013/06/07 14:42:55 (state_ == REQUESTING) means another Request() is
MAD 2013/06/07 15:02:15 As I mentioned below, if callback == callback_ whe
Takashi Toyoshima 2013/06/10 13:36:57 Ah, now I understand what you concerned about. I
174 return;
175 }
176
177 state_ = REQUESTING;
178 callback_ = callback;
179
180 GURL url = GURL(kLanguageListFetchURL);
181 url = TranslateURLUtil::AddHostLocaleToUrl(url);
182 url = TranslateURLUtil::AddApiKeyToUrl(url);
183 if (include_alpha_languages_) {
184 url = net::AppendQueryParameter(url,
185 kAlphaLanguageQueryName,
186 kAlphaLanguageQueryValue);
187 }
188
162 VLOG(9) << "Fetch supporting language list from: " << url.spec().c_str(); 189 VLOG(9) << "Fetch supporting language list from: " << url.spec().c_str();
Takashi Toyoshima 2013/06/07 05:17:17 FYI, VLOG(9) will be replace with translate-intern
MAD 2013/06/07 15:02:15 OK.
163 190
164 scoped_ptr<net::URLFetcher> fetcher; 191 fetcher_.reset(net::URLFetcher::Create(include_alpha_languages_ ? 2 : 1,
MAD 2013/06/07 13:29:24 I didn't notice in previous version that we were u
Takashi Toyoshima 2013/06/07 14:42:55 In another change, I defined const int for these 1
MAD 2013/06/07 15:02:15 OK thanks.
Takashi Toyoshima 2013/06/10 13:36:57 Done.
165 fetcher.reset(net::URLFetcher::Create(id, 192 url,
166 url, 193 net::URLFetcher::GET,
167 net::URLFetcher::GET, 194 this));
168 delegate)); 195 fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES |
169 fetcher->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES | 196 net::LOAD_DO_NOT_SAVE_COOKIES);
170 net::LOAD_DO_NOT_SAVE_COOKIES); 197 fetcher_->SetRequestContext(g_browser_process->system_request_context());
171 fetcher->SetRequestContext(g_browser_process->system_request_context()); 198 fetcher_->SetMaxRetriesOn5xx(kMaxRetryLanguageListFetch);
172 fetcher->SetMaxRetriesOn5xx(kMaxRetryLanguageListFetch); 199 fetcher_->Start();
173 fetcher->Start();
174
175 return fetcher.release();
176 } 200 }
177 201
178 } // namespace 202 void TranslateLanguageList::LanguageListFetcher::OnURLFetchComplete(
203 const net::URLFetcher* source) {
204 DCHECK(fetcher_.get() == source);
205
206 scoped_ptr<const net::URLFetcher> delete_ptr(fetcher_.release());
hajimehoshi 2013/06/07 04:15:44 Remove this line (as we discussed).
Takashi Toyoshima 2013/06/07 05:17:17 Thanks. And after another discussion, I notice tha
207
208 if (source->GetStatus().status() == net::URLRequestStatus::SUCCESS &&
209 source->GetResponseCode() == net::HTTP_OK) {
210 state_ = COMPLETED;
211 std::string data;
212 source->GetResponseAsString(&data);
213 callback_.Run(include_alpha_languages_, true, data);
214 } else {
215 // TODO(toyoshim): Try again. http://crbug.com/244202 .
216 // Also In CrOS, FetchLanguageList is not called at launching Chrome. It
217 // will solve this problem that check if FetchLanguageList is already
218 // called, and call it if needed in InitSupportedLanguage().
219 VLOG(9) << "Failed to Fetch languages from: " << kLanguageListFetchURL;
220 state_ = FAILED;
221 callback_.Run(include_alpha_languages_, false, std::string());
222 }
223 }
179 224
180 // This must be kept in sync with the &cb= value in the kLanguageListFetchURL. 225 // This must be kept in sync with the &cb= value in the kLanguageListFetchURL.
181 const char TranslateLanguageList::kLanguageListCallbackName[] = "sl("; 226 const char TranslateLanguageList::kLanguageListCallbackName[] = "sl(";
182 const char TranslateLanguageList::kTargetLanguagesKey[] = "tl"; 227 const char TranslateLanguageList::kTargetLanguagesKey[] = "tl";
183 228
184 TranslateLanguageList::TranslateLanguageList() { 229 TranslateLanguageList::TranslateLanguageList() {
185 // We default to our hard coded list of languages in 230 // We default to our hard coded list of languages in
186 // |kDefaultSupportedLanguages|. This list will be overriden by a server 231 // |kDefaultSupportedLanguages|. This list will be overriden by a server
187 // providing supported langauges list. 232 // providing supported langauges list.
188 for (size_t i = 0; i < arraysize(kDefaultSupportedLanguages); ++i) 233 for (size_t i = 0; i < arraysize(kDefaultSupportedLanguages); ++i)
189 supported_languages_.insert(kDefaultSupportedLanguages[i]); 234 supported_languages_.insert(kDefaultSupportedLanguages[i]);
190 UpdateSupportedLanguages(); 235 UpdateSupportedLanguages();
236
237 language_list_fetcher_.reset(new LanguageListFetcher(false));
238 alpha_language_list_fetcher_.reset(new LanguageListFetcher(true));
239
240 net::NetworkChangeNotifier::AddNetworkChangeObserver(this);
191 } 241 }
192 242
193 TranslateLanguageList::~TranslateLanguageList() {} 243 TranslateLanguageList::~TranslateLanguageList() {
194 244 net::NetworkChangeNotifier::RemoveNetworkChangeObserver(this);
195 void TranslateLanguageList::OnURLFetchComplete(const net::URLFetcher* source) {
196 scoped_ptr<const net::URLFetcher> delete_ptr;
197
198 if (source->GetStatus().status() == net::URLRequestStatus::SUCCESS &&
199 source->GetResponseCode() == net::HTTP_OK) {
200 std::string data;
201 source->GetResponseAsString(&data);
202 if (language_list_fetcher_.get() == source) {
203 delete_ptr.reset(language_list_fetcher_.release());
204 SetSupportedLanguages(data, &supported_languages_);
205 } else if (alpha_language_list_fetcher_.get() == source) {
206 delete_ptr.reset(alpha_language_list_fetcher_.release());
207 SetSupportedLanguages(data, &supported_alpha_languages_);
208 } else {
209 NOTREACHED();
210 }
211 UpdateSupportedLanguages();
212 } else {
213 // TODO(toyoshim): Try again. http://crbug.com/244202 .
214 // Also In CrOS, FetchLanguageList is not called at launching Chrome. It
215 // will solve this problem that check if FetchLanguageList is already
216 // called, and call it if needed in InitSupportedLanguage().
217 VLOG(9) << "Failed to Fetch languages from: " << kLanguageListFetchURL;
218 }
219 } 245 }
220 246
221 void TranslateLanguageList::GetSupportedLanguages( 247 void TranslateLanguageList::GetSupportedLanguages(
222 std::vector<std::string>* languages) { 248 std::vector<std::string>* languages) {
223 DCHECK(languages && languages->empty()); 249 DCHECK(languages && languages->empty());
224 std::set<std::string>::const_iterator iter = all_supported_languages_.begin(); 250 std::set<std::string>::const_iterator iter = all_supported_languages_.begin();
225 for (; iter != all_supported_languages_.end(); ++iter) 251 for (; iter != all_supported_languages_.end(); ++iter)
226 languages->push_back(*iter); 252 languages->push_back(*iter);
253
254 // Update language lists if they are not updated after Chrome was launched
255 // for later requests.
256 RequestLanguageList();
227 } 257 }
228 258
229 std::string TranslateLanguageList::GetLanguageCode( 259 std::string TranslateLanguageList::GetLanguageCode(
230 const std::string& chrome_locale) { 260 const std::string& chrome_locale) {
231 // Only remove the country code for country specific languages we don't 261 // Only remove the country code for country specific languages we don't
232 // support specifically yet. 262 // support specifically yet.
233 if (IsSupportedLanguage(chrome_locale)) 263 if (IsSupportedLanguage(chrome_locale))
234 return chrome_locale; 264 return chrome_locale;
235 265
236 size_t hypen_index = chrome_locale.find('-'); 266 size_t hypen_index = chrome_locale.find('-');
237 if (hypen_index == std::string::npos) 267 if (hypen_index == std::string::npos)
238 return chrome_locale; 268 return chrome_locale;
239 return chrome_locale.substr(0, hypen_index); 269 return chrome_locale.substr(0, hypen_index);
240 } 270 }
241 271
242 bool TranslateLanguageList::IsSupportedLanguage(const std::string& language) { 272 bool TranslateLanguageList::IsSupportedLanguage(const std::string& language) {
243 return all_supported_languages_.count(language) != 0; 273 return all_supported_languages_.count(language) != 0;
244 } 274 }
245 275
246 bool TranslateLanguageList::IsAlphaLanguage(const std::string& language) { 276 bool TranslateLanguageList::IsAlphaLanguage(const std::string& language) {
247 // |language| should exist only in the alpha language list. 277 // |language| should exist only in the alpha language list.
248 return supported_alpha_languages_.count(language) != 0 && 278 return supported_alpha_languages_.count(language) != 0 &&
249 supported_languages_.count(language) == 0; 279 supported_languages_.count(language) == 0;
250 } 280 }
251 281
252 void TranslateLanguageList::RequestLanguageList() { 282 void TranslateLanguageList::RequestLanguageList() {
253 if (language_list_fetcher_.get() || alpha_language_list_fetcher_.get()) 283 if (language_list_fetcher_.get() &&
284 (language_list_fetcher_->state() == LanguageListFetcher::IDLE ||
285 language_list_fetcher_->state() == LanguageListFetcher::FAILED)) {
286 language_list_fetcher_->Request(
287 base::Bind(&TranslateLanguageList::OnLanguageListFetchComplete,
288 base::Unretained(this)));
289 }
290
291 if (alpha_language_list_fetcher_.get() &&
292 (alpha_language_list_fetcher_->state() == LanguageListFetcher::IDLE ||
293 alpha_language_list_fetcher_->state() == LanguageListFetcher::FAILED)) {
294 alpha_language_list_fetcher_->Request(
295 base::Bind(&TranslateLanguageList::OnLanguageListFetchComplete,
296 base::Unretained(this)));
297 }
298 }
299
300 void TranslateLanguageList::OnNetworkChanged(
301 net::NetworkChangeNotifier::ConnectionType type) {
302 VLOG(9) << "OnNetworkChanged: " << type << ", "
303 << (net::NetworkChangeNotifier::IsOffline() ? " offline" : "online");
304 if (net::NetworkChangeNotifier::IsOffline())
305 return;
306 RequestLanguageList();
307 }
308
309 void TranslateLanguageList::OnLanguageListFetchComplete(
310 bool include_alpha_languages,
311 bool success,
312 const std::string& data) {
313 if (!success)
MAD 2013/06/07 13:29:24 If we would only call here when there's a real err
Takashi Toyoshima 2013/06/07 14:42:55 Retry is issued when network status is changed to
MAD 2013/06/07 15:02:15 And what I meant is that, since you return an erro
Takashi Toyoshima 2013/06/10 13:36:57 Thank you for clarification. After understanding y
254 return; 314 return;
255 315
256 // Fetch the stable language list. 316 if (!include_alpha_languages) {
257 GURL language_list_fetch_url = GURL(kLanguageListFetchURL); 317 SetSupportedLanguages(data, &supported_languages_);
258 language_list_fetch_url = 318 language_list_fetcher_.reset();
259 TranslateURLUtil::AddHostLocaleToUrl(language_list_fetch_url); 319 } else {
260 language_list_fetch_url = 320 SetSupportedLanguages(data, &supported_alpha_languages_);
261 TranslateURLUtil::AddApiKeyToUrl(language_list_fetch_url); 321 alpha_language_list_fetcher_.reset();
262 322 }
263 language_list_fetcher_.reset( 323 UpdateSupportedLanguages();
264 CreateAndStartFetch(1, language_list_fetch_url, this));
265
266 // Fetch the alpha language list.
267 language_list_fetch_url = net::AppendQueryParameter(
268 language_list_fetch_url,
269 kAlphaLanguageQueryName,
270 kAlphaLanguageQueryValue);
271
272 alpha_language_list_fetcher_.reset(
273 CreateAndStartFetch(2, language_list_fetch_url, this));
274 } 324 }
275 325
276 void TranslateLanguageList::UpdateSupportedLanguages() { 326 void TranslateLanguageList::UpdateSupportedLanguages() {
277 all_supported_languages_.clear(); 327 all_supported_languages_.clear();
278 std::set<std::string>::const_iterator iter; 328 std::set<std::string>::const_iterator iter;
279 for (iter = supported_languages_.begin(); 329 for (iter = supported_languages_.begin();
280 iter != supported_languages_.end(); 330 iter != supported_languages_.end();
281 ++iter) 331 ++iter)
282 all_supported_languages_.insert(*iter); 332 all_supported_languages_.insert(*iter);
283 for (iter = supported_alpha_languages_.begin(); 333 for (iter = supported_alpha_languages_.begin();
284 iter != supported_alpha_languages_.end(); 334 iter != supported_alpha_languages_.end();
285 ++iter) 335 ++iter)
286 all_supported_languages_.insert(*iter); 336 all_supported_languages_.insert(*iter);
287 } 337 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698