• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "components/translate/core/browser/translate_ui_delegate.h"
6 
7 #include "base/i18n/string_compare.h"
8 #include "base/metrics/histogram.h"
9 #include "components/translate/core/browser/language_state.h"
10 #include "components/translate/core/browser/translate_client.h"
11 #include "components/translate/core/browser/translate_download_manager.h"
12 #include "components/translate/core/browser/translate_driver.h"
13 #include "components/translate/core/browser/translate_manager.h"
14 #include "components/translate/core/browser/translate_prefs.h"
15 #include "components/translate/core/common/translate_constants.h"
16 #include "third_party/icu/source/i18n/unicode/coll.h"
17 #include "ui/base/l10n/l10n_util.h"
18 
19 namespace {
20 
21 const char kDeclineTranslate[] = "Translate.DeclineTranslate";
22 const char kRevertTranslation[] = "Translate.RevertTranslation";
23 const char kPerformTranslate[] = "Translate.Translate";
24 const char kNeverTranslateLang[] = "Translate.NeverTranslateLang";
25 const char kNeverTranslateSite[] = "Translate.NeverTranslateSite";
26 const char kAlwaysTranslateLang[] = "Translate.AlwaysTranslateLang";
27 const char kModifyOriginalLang[] = "Translate.ModifyOriginalLang";
28 const char kModifyTargetLang[] = "Translate.ModifyTargetLang";
29 const char kDeclineTranslateDismissUI[] = "Translate.DeclineTranslateDismissUI";
30 const char kShowErrorUI[] = "Translate.ShowErrorUI";
31 
32 }  // namespace
33 
TranslateUIDelegate(const base::WeakPtr<TranslateManager> & translate_manager,const std::string & original_language,const std::string & target_language)34 TranslateUIDelegate::TranslateUIDelegate(
35     const base::WeakPtr<TranslateManager>& translate_manager,
36     const std::string& original_language,
37     const std::string& target_language)
38     : translate_driver_(
39           translate_manager->translate_client()->GetTranslateDriver()),
40       translate_manager_(translate_manager),
41       original_language_index_(NO_INDEX),
42       initial_original_language_index_(NO_INDEX),
43       target_language_index_(NO_INDEX) {
44   DCHECK(translate_driver_);
45   DCHECK(translate_manager_);
46 
47   std::vector<std::string> language_codes;
48   TranslateDownloadManager::GetSupportedLanguages(&language_codes);
49 
50   // Preparing for the alphabetical order in the locale.
51   UErrorCode error = U_ZERO_ERROR;
52   std::string locale =
53       TranslateDownloadManager::GetInstance()->application_locale();
54   icu::Locale loc(locale.c_str());
55   scoped_ptr<icu::Collator> collator(icu::Collator::createInstance(loc, error));
56   collator->setStrength(icu::Collator::PRIMARY);
57 
58   languages_.reserve(language_codes.size());
59   for (std::vector<std::string>::const_iterator iter = language_codes.begin();
60        iter != language_codes.end();
61        ++iter) {
62     std::string language_code = *iter;
63 
64     base::string16 language_name =
65         l10n_util::GetDisplayNameForLocale(language_code, locale, true);
66     // Insert the language in languages_ in alphabetical order.
67     std::vector<LanguageNamePair>::iterator iter2;
68     for (iter2 = languages_.begin(); iter2 != languages_.end(); ++iter2) {
69       if (base::i18n::CompareString16WithCollator(
70               collator.get(), language_name, iter2->second) == UCOL_LESS) {
71         break;
72       }
73     }
74     languages_.insert(iter2, LanguageNamePair(language_code, language_name));
75   }
76   for (std::vector<LanguageNamePair>::const_iterator iter = languages_.begin();
77        iter != languages_.end();
78        ++iter) {
79     std::string language_code = iter->first;
80     if (language_code == original_language) {
81       original_language_index_ = iter - languages_.begin();
82       initial_original_language_index_ = original_language_index_;
83     }
84     if (language_code == target_language)
85       target_language_index_ = iter - languages_.begin();
86   }
87 
88   prefs_ = translate_manager_->translate_client()->GetTranslatePrefs();
89 }
90 
~TranslateUIDelegate()91 TranslateUIDelegate::~TranslateUIDelegate() {}
92 
OnErrorShown(TranslateErrors::Type error_type)93 void TranslateUIDelegate::OnErrorShown(TranslateErrors::Type error_type) {
94   DCHECK_LE(TranslateErrors::NONE, error_type);
95   DCHECK_LT(error_type, TranslateErrors::TRANSLATE_ERROR_MAX);
96 
97   if (error_type == TranslateErrors::NONE)
98     return;
99 
100   UMA_HISTOGRAM_ENUMERATION(
101       kShowErrorUI, error_type, TranslateErrors::TRANSLATE_ERROR_MAX);
102 }
103 
GetLanguageState()104 const LanguageState& TranslateUIDelegate::GetLanguageState() {
105   return translate_manager_->GetLanguageState();
106 }
107 
GetNumberOfLanguages() const108 size_t TranslateUIDelegate::GetNumberOfLanguages() const {
109   return languages_.size();
110 }
111 
GetOriginalLanguageIndex() const112 size_t TranslateUIDelegate::GetOriginalLanguageIndex() const {
113   return original_language_index_;
114 }
115 
UpdateOriginalLanguageIndex(size_t language_index)116 void TranslateUIDelegate::UpdateOriginalLanguageIndex(size_t language_index) {
117   if (original_language_index_ == language_index)
118     return;
119 
120   UMA_HISTOGRAM_BOOLEAN(kModifyOriginalLang, true);
121   original_language_index_ = language_index;
122 }
123 
GetTargetLanguageIndex() const124 size_t TranslateUIDelegate::GetTargetLanguageIndex() const {
125   return target_language_index_;
126 }
127 
UpdateTargetLanguageIndex(size_t language_index)128 void TranslateUIDelegate::UpdateTargetLanguageIndex(size_t language_index) {
129   if (target_language_index_ == language_index)
130     return;
131 
132   DCHECK_LT(language_index, GetNumberOfLanguages());
133   UMA_HISTOGRAM_BOOLEAN(kModifyTargetLang, true);
134   target_language_index_ = language_index;
135 }
136 
GetLanguageCodeAt(size_t index) const137 std::string TranslateUIDelegate::GetLanguageCodeAt(size_t index) const {
138   DCHECK_LT(index, GetNumberOfLanguages());
139   return languages_[index].first;
140 }
141 
GetLanguageNameAt(size_t index) const142 base::string16 TranslateUIDelegate::GetLanguageNameAt(size_t index) const {
143   if (index == static_cast<size_t>(NO_INDEX))
144     return base::string16();
145   DCHECK_LT(index, GetNumberOfLanguages());
146   return languages_[index].second;
147 }
148 
GetOriginalLanguageCode() const149 std::string TranslateUIDelegate::GetOriginalLanguageCode() const {
150   return (GetOriginalLanguageIndex() == static_cast<size_t>(NO_INDEX))
151              ? translate::kUnknownLanguageCode
152              : GetLanguageCodeAt(GetOriginalLanguageIndex());
153 }
154 
GetTargetLanguageCode() const155 std::string TranslateUIDelegate::GetTargetLanguageCode() const {
156   return GetLanguageCodeAt(GetTargetLanguageIndex());
157 }
158 
Translate()159 void TranslateUIDelegate::Translate() {
160   if (!translate_driver_->IsOffTheRecord()) {
161     prefs_->ResetTranslationDeniedCount(GetOriginalLanguageCode());
162     prefs_->IncrementTranslationAcceptedCount(GetOriginalLanguageCode());
163   }
164 
165   if (translate_manager_) {
166     translate_manager_->TranslatePage(
167         GetOriginalLanguageCode(), GetTargetLanguageCode(), false);
168     UMA_HISTOGRAM_BOOLEAN(kPerformTranslate, true);
169   }
170 }
171 
RevertTranslation()172 void TranslateUIDelegate::RevertTranslation() {
173   if (translate_manager_) {
174     translate_manager_->RevertTranslation();
175     UMA_HISTOGRAM_BOOLEAN(kRevertTranslation, true);
176   }
177 }
178 
TranslationDeclined(bool explicitly_closed)179 void TranslateUIDelegate::TranslationDeclined(bool explicitly_closed) {
180   if (!translate_driver_->IsOffTheRecord()) {
181     prefs_->ResetTranslationAcceptedCount(GetOriginalLanguageCode());
182     prefs_->IncrementTranslationDeniedCount(GetOriginalLanguageCode());
183   }
184 
185   // Remember that the user declined the translation so as to prevent showing a
186   // translate infobar for that page again.  (TranslateManager initiates
187   // translations when getting a LANGUAGE_DETERMINED from the page, which
188   // happens when a load stops. That could happen multiple times, including
189   // after the user already declined the translation.)
190   if (translate_manager_) {
191     translate_manager_->GetLanguageState().set_translation_declined(true);
192     UMA_HISTOGRAM_BOOLEAN(kDeclineTranslate, true);
193   }
194 
195   if (!explicitly_closed)
196     UMA_HISTOGRAM_BOOLEAN(kDeclineTranslateDismissUI, true);
197 }
198 
IsLanguageBlocked()199 bool TranslateUIDelegate::IsLanguageBlocked() {
200   return prefs_->IsBlockedLanguage(GetOriginalLanguageCode());
201 }
202 
SetLanguageBlocked(bool value)203 void TranslateUIDelegate::SetLanguageBlocked(bool value) {
204   if (value) {
205     prefs_->BlockLanguage(GetOriginalLanguageCode());
206     if (translate_manager_) {
207       translate_manager_->GetLanguageState().SetTranslateEnabled(false);
208     }
209   } else {
210     prefs_->UnblockLanguage(GetOriginalLanguageCode());
211   }
212 
213   UMA_HISTOGRAM_BOOLEAN(kNeverTranslateLang, true);
214 }
215 
IsSiteBlacklisted()216 bool TranslateUIDelegate::IsSiteBlacklisted() {
217   std::string host = GetPageHost();
218   return !host.empty() && prefs_->IsSiteBlacklisted(host);
219 }
220 
SetSiteBlacklist(bool value)221 void TranslateUIDelegate::SetSiteBlacklist(bool value) {
222   std::string host = GetPageHost();
223   if (host.empty())
224     return;
225 
226   if (value) {
227     prefs_->BlacklistSite(host);
228     if (translate_manager_) {
229       translate_manager_->GetLanguageState().SetTranslateEnabled(false);
230     }
231   } else {
232     prefs_->RemoveSiteFromBlacklist(host);
233   }
234 
235   UMA_HISTOGRAM_BOOLEAN(kNeverTranslateSite, true);
236 }
237 
ShouldAlwaysTranslate()238 bool TranslateUIDelegate::ShouldAlwaysTranslate() {
239   return prefs_->IsLanguagePairWhitelisted(GetOriginalLanguageCode(),
240                                            GetTargetLanguageCode());
241 }
242 
SetAlwaysTranslate(bool value)243 void TranslateUIDelegate::SetAlwaysTranslate(bool value) {
244   const std::string& original_lang = GetOriginalLanguageCode();
245   const std::string& target_lang = GetTargetLanguageCode();
246   if (value)
247     prefs_->WhitelistLanguagePair(original_lang, target_lang);
248   else
249     prefs_->RemoveLanguagePairFromWhitelist(original_lang, target_lang);
250 
251   UMA_HISTOGRAM_BOOLEAN(kAlwaysTranslateLang, true);
252 }
253 
GetPageHost()254 std::string TranslateUIDelegate::GetPageHost() {
255   if (!translate_driver_->HasCurrentPage())
256     return std::string();
257   return translate_driver_->GetActiveURL().HostNoBrackets();
258 }
259