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