• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 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_prefs.h"
6 
7 #include "base/string_util.h"
8 #include "chrome/browser/prefs/pref_service.h"
9 #include "chrome/browser/prefs/scoped_user_pref_update.h"
10 
11 const char TranslatePrefs::kPrefTranslateLanguageBlacklist[] =
12     "translate_language_blacklist";
13 const char TranslatePrefs::kPrefTranslateSiteBlacklist[] =
14     "translate_site_blacklist";
15 const char TranslatePrefs::kPrefTranslateWhitelists[] =
16     "translate_whitelists";
17 const char TranslatePrefs::kPrefTranslateDeniedCount[] =
18     "translate_denied_count";
19 const char TranslatePrefs::kPrefTranslateAcceptedCount[] =
20     "translate_accepted_count";
21 
22 // TranslatePrefs: public: -----------------------------------------------------
23 
TranslatePrefs(PrefService * user_prefs)24 TranslatePrefs::TranslatePrefs(PrefService* user_prefs)
25     : prefs_(user_prefs) {
26 }
27 
IsLanguageBlacklisted(const std::string & original_language)28 bool TranslatePrefs::IsLanguageBlacklisted(
29     const std::string& original_language) {
30   return IsValueBlacklisted(kPrefTranslateLanguageBlacklist, original_language);
31 }
32 
BlacklistLanguage(const std::string & original_language)33 void TranslatePrefs::BlacklistLanguage(const std::string& original_language) {
34   BlacklistValue(kPrefTranslateLanguageBlacklist, original_language);
35 }
36 
RemoveLanguageFromBlacklist(const std::string & original_language)37 void TranslatePrefs::RemoveLanguageFromBlacklist(
38     const std::string& original_language) {
39   RemoveValueFromBlacklist(kPrefTranslateLanguageBlacklist, original_language);
40 }
41 
IsSiteBlacklisted(const std::string & site)42 bool TranslatePrefs::IsSiteBlacklisted(const std::string& site) {
43   return IsValueBlacklisted(kPrefTranslateSiteBlacklist, site);
44 }
45 
BlacklistSite(const std::string & site)46 void TranslatePrefs::BlacklistSite(const std::string& site) {
47   BlacklistValue(kPrefTranslateSiteBlacklist, site);
48 }
49 
RemoveSiteFromBlacklist(const std::string & site)50 void TranslatePrefs::RemoveSiteFromBlacklist(const std::string& site) {
51   RemoveValueFromBlacklist(kPrefTranslateSiteBlacklist, site);
52 }
53 
IsLanguagePairWhitelisted(const std::string & original_language,const std::string & target_language)54 bool TranslatePrefs::IsLanguagePairWhitelisted(
55     const std::string& original_language,
56     const std::string& target_language) {
57   const DictionaryValue* dict = prefs_->GetDictionary(kPrefTranslateWhitelists);
58   if (dict && !dict->empty()) {
59     std::string auto_target_lang;
60     if (dict->GetString(original_language, &auto_target_lang) &&
61         auto_target_lang == target_language)
62       return true;
63   }
64   return false;
65 }
66 
WhitelistLanguagePair(const std::string & original_language,const std::string & target_language)67 void TranslatePrefs::WhitelistLanguagePair(
68     const std::string& original_language,
69     const std::string& target_language) {
70   DictionaryPrefUpdate update(prefs_, kPrefTranslateWhitelists);
71   DictionaryValue* dict = update.Get();
72   if (!dict) {
73     NOTREACHED() << "Unregistered translate whitelist pref";
74     return;
75   }
76   dict->SetString(original_language, target_language);
77   prefs_->ScheduleSavePersistentPrefs();
78 }
79 
RemoveLanguagePairFromWhitelist(const std::string & original_language,const std::string & target_language)80 void TranslatePrefs::RemoveLanguagePairFromWhitelist(
81     const std::string& original_language,
82     const std::string& target_language) {
83   DictionaryPrefUpdate update(prefs_, kPrefTranslateWhitelists);
84   DictionaryValue* dict = update.Get();
85   if (!dict) {
86     NOTREACHED() << "Unregistered translate whitelist pref";
87     return;
88   }
89   if (dict->Remove(original_language, NULL))
90     prefs_->ScheduleSavePersistentPrefs();
91 }
92 
GetTranslationDeniedCount(const std::string & language)93 int TranslatePrefs::GetTranslationDeniedCount(const std::string& language) {
94   const DictionaryValue* dict =
95       prefs_->GetDictionary(kPrefTranslateDeniedCount);
96   int count = 0;
97   return dict->GetInteger(language, &count) ? count : 0;
98 }
99 
IncrementTranslationDeniedCount(const std::string & language)100 void TranslatePrefs::IncrementTranslationDeniedCount(
101     const std::string& language) {
102   DictionaryPrefUpdate update(prefs_, kPrefTranslateDeniedCount);
103   DictionaryValue* dict = update.Get();
104 
105   int count = 0;
106   dict->GetInteger(language, &count);
107   dict->SetInteger(language, count + 1);
108 }
109 
ResetTranslationDeniedCount(const std::string & language)110 void TranslatePrefs::ResetTranslationDeniedCount(const std::string& language) {
111   DictionaryPrefUpdate update(prefs_, kPrefTranslateDeniedCount);
112   update.Get()->SetInteger(language, 0);
113 }
114 
GetTranslationAcceptedCount(const std::string & language)115 int TranslatePrefs::GetTranslationAcceptedCount(const std::string& language) {
116   const DictionaryValue* dict =
117       prefs_->GetDictionary(kPrefTranslateAcceptedCount);
118   int count = 0;
119   return dict->GetInteger(language, &count) ? count : 0;
120 }
121 
IncrementTranslationAcceptedCount(const std::string & language)122 void TranslatePrefs::IncrementTranslationAcceptedCount(
123     const std::string& language) {
124   DictionaryPrefUpdate update(prefs_, kPrefTranslateAcceptedCount);
125   DictionaryValue* dict = update.Get();
126   int count = 0;
127   dict->GetInteger(language, &count);
128   dict->SetInteger(language, count + 1);
129 }
130 
ResetTranslationAcceptedCount(const std::string & language)131 void TranslatePrefs::ResetTranslationAcceptedCount(
132     const std::string& language) {
133   DictionaryPrefUpdate update(prefs_, kPrefTranslateAcceptedCount);
134   update.Get()->SetInteger(language, 0);
135 }
136 
137 // TranslatePrefs: public, static: ---------------------------------------------
138 
CanTranslate(PrefService * user_prefs,const std::string & original_language,const GURL & url)139 bool TranslatePrefs::CanTranslate(PrefService* user_prefs,
140     const std::string& original_language, const GURL& url) {
141   TranslatePrefs prefs(user_prefs);
142   if (prefs.IsSiteBlacklisted(url.HostNoBrackets()))
143     return false;
144   return (!prefs.IsLanguageBlacklisted(original_language));
145 }
146 
ShouldAutoTranslate(PrefService * user_prefs,const std::string & original_language,std::string * target_language)147 bool TranslatePrefs::ShouldAutoTranslate(PrefService* user_prefs,
148     const std::string& original_language, std::string* target_language) {
149   TranslatePrefs prefs(user_prefs);
150   return prefs.IsLanguageWhitelisted(original_language, target_language);
151 }
152 
RegisterUserPrefs(PrefService * user_prefs)153 void TranslatePrefs::RegisterUserPrefs(PrefService* user_prefs) {
154   if (!user_prefs->FindPreference(kPrefTranslateLanguageBlacklist))
155     user_prefs->RegisterListPref(kPrefTranslateLanguageBlacklist);
156   if (!user_prefs->FindPreference(kPrefTranslateSiteBlacklist))
157     user_prefs->RegisterListPref(kPrefTranslateSiteBlacklist);
158   if (!user_prefs->FindPreference(kPrefTranslateWhitelists)) {
159     user_prefs->RegisterDictionaryPref(kPrefTranslateWhitelists);
160     MigrateTranslateWhitelists(user_prefs);
161   }
162   if (!user_prefs->FindPreference(kPrefTranslateDeniedCount))
163     user_prefs->RegisterDictionaryPref(kPrefTranslateDeniedCount);
164   if (!user_prefs->FindPreference(kPrefTranslateAcceptedCount))
165     user_prefs->RegisterDictionaryPref(kPrefTranslateAcceptedCount);
166 }
167 
168 // TranslatePrefs: private, static: --------------------------------------------
169 
MigrateTranslateWhitelists(PrefService * user_prefs)170 void TranslatePrefs::MigrateTranslateWhitelists(PrefService* user_prefs) {
171   // Old format of kPrefTranslateWhitelists
172   // - original language -> list of target langs to auto-translate
173   // - list of langs is in order of being enabled i.e. last in list is the
174   //   most recent language that user enabled via
175   //   Always translate |source_lang| to |target_lang|"
176   // - this results in a one-to-n relationship between source lang and target
177   //   langs.
178   // New format:
179   // - original language -> one target language to auto-translate
180   // - each time that the user enables the "Always translate..." option, that
181   //   target lang overwrites the previous one.
182   // - this results in a one-to-one relationship between source lang and target
183   //   lang
184   // - we replace old list of target langs with the last target lang in list,
185   //   assuming the last (i.e. most recent) target lang is what user wants to
186   //   keep auto-translated.
187   DictionaryPrefUpdate update(user_prefs, kPrefTranslateWhitelists);
188   DictionaryValue* dict = update.Get();
189   if (!dict || dict->empty())
190     return;
191   bool save_prefs = false;
192   for (DictionaryValue::key_iterator iter(dict->begin_keys());
193        iter != dict->end_keys(); ++iter) {
194     ListValue* list = NULL;
195     if (!dict->GetList(*iter, &list) || !list)
196       break;  // Dictionary has either been migrated or new format.
197     save_prefs = true;
198     std::string target_lang;
199     if (list->empty() || !list->GetString(list->GetSize() - 1, &target_lang) ||
200         target_lang.empty())
201       dict->Remove(*iter, NULL);
202      else
203       dict->SetString(*iter, target_lang);
204   }
205   if (!save_prefs)
206     return;
207   user_prefs->ScheduleSavePersistentPrefs();
208 }
209 
210 // TranslatePrefs: private: ----------------------------------------------------
211 
IsValueInList(const ListValue * list,const std::string & in_value)212 bool TranslatePrefs::IsValueInList(const ListValue* list,
213     const std::string& in_value) {
214   for (size_t i = 0; i < list->GetSize(); ++i) {
215     std::string value;
216     if (list->GetString(i, &value) && value == in_value)
217       return true;
218   }
219   return false;
220 }
221 
IsValueBlacklisted(const char * pref_id,const std::string & value)222 bool TranslatePrefs::IsValueBlacklisted(const char* pref_id,
223     const std::string& value) {
224   const ListValue* blacklist = prefs_->GetList(pref_id);
225   return (blacklist && !blacklist->empty() && IsValueInList(blacklist, value));
226 }
227 
BlacklistValue(const char * pref_id,const std::string & value)228 void TranslatePrefs::BlacklistValue(const char* pref_id,
229     const std::string& value) {
230   {
231     ListPrefUpdate update(prefs_, pref_id);
232     ListValue* blacklist = update.Get();
233     if (!blacklist) {
234       NOTREACHED() << "Unregistered translate blacklist pref";
235       return;
236     }
237     blacklist->Append(new StringValue(value));
238   }
239   prefs_->ScheduleSavePersistentPrefs();
240 }
241 
RemoveValueFromBlacklist(const char * pref_id,const std::string & value)242 void TranslatePrefs::RemoveValueFromBlacklist(const char* pref_id,
243     const std::string& value) {
244   bool schedule_save = false;
245   {
246     ListPrefUpdate update(prefs_, pref_id);
247     ListValue* blacklist = update.Get();
248     if (!blacklist) {
249       NOTREACHED() << "Unregistered translate blacklist pref";
250       return;
251     }
252     StringValue string_value(value);
253     schedule_save = blacklist->Remove(string_value) != -1;
254   }
255   if (schedule_save)
256     prefs_->ScheduleSavePersistentPrefs();
257 }
258 
IsLanguageWhitelisted(const std::string & original_language,std::string * target_language)259 bool TranslatePrefs::IsLanguageWhitelisted(
260     const std::string& original_language, std::string* target_language) {
261   const DictionaryValue* dict = prefs_->GetDictionary(kPrefTranslateWhitelists);
262   if (dict && dict->GetString(original_language, target_language)) {
263     DCHECK(!target_language->empty());
264     return !target_language->empty();
265   }
266   return false;
267 }
268