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