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/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 Loading... | |
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 } |
OLD | NEW |