Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(696)

Side by Side Diff: chrome/browser/spellchecker/spellcheck_service.cc

Issue 2159283003: [WIP][DO NOT LAND] Componentize spellcheck Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/spellchecker/spellcheck_service.h" 5 #include "chrome/browser/spellchecker/spellcheck_service.h"
6 6
7 #include <set> 7 #include <set>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/strings/string_split.h" 10 #include "base/strings/string_split.h"
11 #include "base/supports_user_data.h" 11 #include "base/supports_user_data.h"
12 #include "base/synchronization/waitable_event.h" 12 #include "base/synchronization/waitable_event.h"
13 #include "build/build_config.h" 13 #include "build/build_config.h"
14 #include "chrome/browser/spellchecker/feedback_sender.h" 14 #include "components/spellcheck/browser/feedback_sender.h"
15 #include "chrome/browser/spellchecker/spellcheck_factory.h" 15 #include "chrome/browser/spellchecker/spellcheck_factory.h"
16 #include "chrome/browser/spellchecker/spellcheck_host_metrics.h" 16 #include "components/spellcheck/browser/spellcheck_host_metrics.h"
17 #include "chrome/browser/spellchecker/spellcheck_hunspell_dictionary.h" 17 #include "chrome/browser/spellchecker/spellcheck_hunspell_dictionary.h"
18 #include "chrome/browser/spellchecker/spellcheck_platform.h" 18 #include "components/spellcheck/browser/spellcheck_platform.h"
19 #include "chrome/browser/spellchecker/spelling_service_client.h" 19 #include "components/spellcheck/browser/spelling_service_client.h"
20 #include "chrome/common/pref_names.h" 20 #include "chrome/common/pref_names.h"
21 #include "chrome/common/spellcheck_bdict_language.h" 21 #include "components/spellcheck/browser/pref_names.h"
22 #include "chrome/common/spellcheck_common.h" 22 #include "components/spellcheck/common/spellcheck_bdict_language.h"
23 #include "chrome/common/spellcheck_messages.h" 23 #include "components/spellcheck/common/spellcheck_common.h"
24 #include "components/spellcheck/common/spellcheck_messages.h"
24 #include "components/prefs/pref_member.h" 25 #include "components/prefs/pref_member.h"
25 #include "components/prefs/pref_service.h" 26 #include "components/prefs/pref_service.h"
26 #include "components/user_prefs/user_prefs.h" 27 #include "components/user_prefs/user_prefs.h"
27 #include "content/public/browser/browser_context.h" 28 #include "content/public/browser/browser_context.h"
28 #include "content/public/browser/browser_thread.h" 29 #include "content/public/browser/browser_thread.h"
29 #include "content/public/browser/notification_service.h" 30 #include "content/public/browser/notification_service.h"
30 #include "content/public/browser/notification_types.h" 31 #include "content/public/browser/notification_types.h"
31 #include "content/public/browser/render_process_host.h" 32 #include "content/public/browser/render_process_host.h"
32 #include "content/public/browser/storage_partition.h" 33 #include "content/public/browser/storage_partition.h"
33 #include "ipc/ipc_platform_file.h" 34 #include "ipc/ipc_platform_file.h"
34 35
35 using content::BrowserThread; 36 using content::BrowserThread;
36 37
37 // TODO(rlp): I do not like globals, but keeping these for now during 38 // TODO(rlp): I do not like globals, but keeping these for now during
38 // transition. 39 // transition.
39 // An event used by browser tests to receive status events from this class and 40 // An event used by browser tests to receive status events from this class and
40 // its derived classes. 41 // its derived classes.
41 base::WaitableEvent* g_status_event = NULL; 42 base::WaitableEvent* g_status_event = NULL;
42 SpellcheckService::EventType g_status_type = 43 SpellcheckService::EventType g_status_type =
43 SpellcheckService::BDICT_NOTINITIALIZED; 44 SpellcheckService::BDICT_NOTINITIALIZED;
44 45
45 SpellcheckService::SpellcheckService(content::BrowserContext* context) 46 SpellcheckService::SpellcheckService(content::BrowserContext* context)
46 : context_(context), 47 : context_(context),
47 weak_ptr_factory_(this) { 48 weak_ptr_factory_(this) {
48 DCHECK_CURRENTLY_ON(BrowserThread::UI); 49 DCHECK_CURRENTLY_ON(BrowserThread::UI);
49 PrefService* prefs = user_prefs::UserPrefs::Get(context); 50 PrefService* prefs = user_prefs::UserPrefs::Get(context);
50 pref_change_registrar_.Init(prefs); 51 pref_change_registrar_.Init(prefs);
51 StringListPrefMember dictionaries_pref; 52 StringListPrefMember dictionaries_pref;
52 dictionaries_pref.Init(prefs::kSpellCheckDictionaries, prefs); 53 dictionaries_pref.Init(spellcheck::prefs::kSpellCheckDictionaries, prefs);
53 std::string first_of_dictionaries; 54 std::string first_of_dictionaries;
54 55
55 #if defined(USE_BROWSER_SPELLCHECKER) 56 #if defined(USE_BROWSER_SPELLCHECKER)
56 // Ensure that the renderer always knows the platform spellchecking language. 57 // Ensure that the renderer always knows the platform spellchecking language.
57 // This language is used for initialization of the text iterator. If the 58 // This language is used for initialization of the text iterator. If the
58 // iterator is not initialized, then the context menu does not show spellcheck 59 // iterator is not initialized, then the context menu does not show spellcheck
59 // suggestions. 60 // suggestions.
60 // 61 //
61 // No migration is necessary, because the spellcheck language preference is 62 // No migration is necessary, because the spellcheck language preference is
62 // not user visible or modifiable in Chrome on Mac. 63 // not user visible or modifiable in Chrome on Mac.
63 dictionaries_pref.SetValue(std::vector<std::string>( 64 dictionaries_pref.SetValue(std::vector<std::string>(
64 1, spellcheck_platform::GetSpellCheckerLanguage())); 65 1, spellcheck_platform::GetSpellCheckerLanguage()));
65 first_of_dictionaries = dictionaries_pref.GetValue().front(); 66 first_of_dictionaries = dictionaries_pref.GetValue().front();
66 #else 67 #else
67 // Migrate preferences from single-language to multi-language schema. 68 // Migrate preferences from single-language to multi-language schema.
68 StringPrefMember single_dictionary_pref; 69 StringPrefMember single_dictionary_pref;
69 single_dictionary_pref.Init(prefs::kSpellCheckDictionary, prefs); 70 single_dictionary_pref.Init(spellcheck::prefs::kSpellCheckDictionary, prefs);
70 std::string single_dictionary = single_dictionary_pref.GetValue(); 71 std::string single_dictionary = single_dictionary_pref.GetValue();
71 72
72 if (!dictionaries_pref.GetValue().empty()) 73 if (!dictionaries_pref.GetValue().empty())
73 first_of_dictionaries = dictionaries_pref.GetValue().front(); 74 first_of_dictionaries = dictionaries_pref.GetValue().front();
74 75
75 if (first_of_dictionaries.empty() && !single_dictionary.empty()) { 76 if (first_of_dictionaries.empty() && !single_dictionary.empty()) {
76 first_of_dictionaries = single_dictionary; 77 first_of_dictionaries = single_dictionary;
77 dictionaries_pref.SetValue( 78 dictionaries_pref.SetValue(
78 std::vector<std::string>(1, first_of_dictionaries)); 79 std::vector<std::string>(1, first_of_dictionaries));
79 } 80 }
80 81
81 single_dictionary_pref.SetValue(""); 82 single_dictionary_pref.SetValue("");
82 #endif // defined(USE_BROWSER_SPELLCHECKER) 83 #endif // defined(USE_BROWSER_SPELLCHECKER)
83 84
84 std::string language_code; 85 std::string language_code;
85 std::string country_code; 86 std::string country_code;
86 chrome::spellcheck_common::GetISOLanguageCountryCodeFromLocale( 87 spellcheck_common::GetISOLanguageCountryCodeFromLocale(
87 first_of_dictionaries, 88 first_of_dictionaries,
88 &language_code, 89 &language_code,
89 &country_code); 90 &country_code);
90 feedback_sender_.reset(new spellcheck::FeedbackSender( 91 feedback_sender_.reset(new spellcheck::FeedbackSender(
91 content::BrowserContext::GetDefaultStoragePartition(context)-> 92 content::BrowserContext::GetDefaultStoragePartition(context)->
92 GetURLRequestContext(), 93 GetURLRequestContext(),
93 language_code, country_code)); 94 language_code, country_code));
94 95
95 pref_change_registrar_.Add( 96 pref_change_registrar_.Add(
96 prefs::kSpellCheckDictionaries, 97 spellcheck::prefs::kSpellCheckDictionaries,
97 base::Bind(&SpellcheckService::OnSpellCheckDictionariesChanged, 98 base::Bind(&SpellcheckService::OnSpellCheckDictionariesChanged,
98 base::Unretained(this))); 99 base::Unretained(this)));
99 pref_change_registrar_.Add( 100 pref_change_registrar_.Add(
100 prefs::kSpellCheckUseSpellingService, 101 spellcheck::prefs::kSpellCheckUseSpellingService,
101 base::Bind(&SpellcheckService::OnUseSpellingServiceChanged, 102 base::Bind(&SpellcheckService::OnUseSpellingServiceChanged,
102 base::Unretained(this))); 103 base::Unretained(this)));
103 pref_change_registrar_.Add( 104 pref_change_registrar_.Add(
104 prefs::kAcceptLanguages, 105 prefs::kAcceptLanguages,
105 base::Bind(&SpellcheckService::OnAcceptLanguagesChanged, 106 base::Bind(&SpellcheckService::OnAcceptLanguagesChanged,
106 base::Unretained(this))); 107 base::Unretained(this)));
107 pref_change_registrar_.Add( 108 pref_change_registrar_.Add(
108 prefs::kEnableContinuousSpellcheck, 109 spellcheck::prefs::kEnableContinuousSpellcheck,
109 base::Bind(&SpellcheckService::InitForAllRenderers, 110 base::Bind(&SpellcheckService::InitForAllRenderers,
110 base::Unretained(this))); 111 base::Unretained(this)));
111 112
112 custom_dictionary_.reset(new SpellcheckCustomDictionary(context_->GetPath())); 113 custom_dictionary_.reset(new SpellcheckCustomDictionary(context_->GetPath()));
113 custom_dictionary_->AddObserver(this); 114 custom_dictionary_->AddObserver(this);
114 custom_dictionary_->Load(); 115 custom_dictionary_->Load();
115 116
116 registrar_.Add(this, 117 registrar_.Add(this,
117 content::NOTIFICATION_RENDERER_PROCESS_CREATED, 118 content::NOTIFICATION_RENDERER_PROCESS_CREATED,
118 content::NotificationService::AllSources()); 119 content::NotificationService::AllSources());
(...skipping 10 matching lines...) Expand all
129 base::WeakPtr<SpellcheckService> SpellcheckService::GetWeakPtr() { 130 base::WeakPtr<SpellcheckService> SpellcheckService::GetWeakPtr() {
130 return weak_ptr_factory_.GetWeakPtr(); 131 return weak_ptr_factory_.GetWeakPtr();
131 } 132 }
132 133
133 #if !defined(OS_MACOSX) 134 #if !defined(OS_MACOSX)
134 // static 135 // static
135 void SpellcheckService::GetDictionaries(base::SupportsUserData* browser_context, 136 void SpellcheckService::GetDictionaries(base::SupportsUserData* browser_context,
136 std::vector<Dictionary>* dictionaries) { 137 std::vector<Dictionary>* dictionaries) {
137 PrefService* prefs = user_prefs::UserPrefs::Get(browser_context); 138 PrefService* prefs = user_prefs::UserPrefs::Get(browser_context);
138 std::set<std::string> spellcheck_dictionaries; 139 std::set<std::string> spellcheck_dictionaries;
139 for (const auto& value : *prefs->GetList(prefs::kSpellCheckDictionaries)) { 140 for (const auto& value : *prefs->GetList(spellcheck::prefs::kSpellCheckDiction aries)) {
140 std::string dictionary; 141 std::string dictionary;
141 if (value->GetAsString(&dictionary)) 142 if (value->GetAsString(&dictionary))
142 spellcheck_dictionaries.insert(dictionary); 143 spellcheck_dictionaries.insert(dictionary);
143 } 144 }
144 145
145 dictionaries->clear(); 146 dictionaries->clear();
146 std::vector<std::string> accept_languages = 147 std::vector<std::string> accept_languages =
147 base::SplitString(prefs->GetString(prefs::kAcceptLanguages), ",", 148 base::SplitString(prefs->GetString(prefs::kAcceptLanguages), ",",
148 base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); 149 base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
149 for (const auto& accept_language : accept_languages) { 150 for (const auto& accept_language : accept_languages) {
150 Dictionary dictionary; 151 Dictionary dictionary;
151 dictionary.language = 152 dictionary.language =
152 chrome::spellcheck_common::GetCorrespondingSpellCheckLanguage( 153 spellcheck_common::GetCorrespondingSpellCheckLanguage(
153 accept_language); 154 accept_language);
154 if (dictionary.language.empty()) 155 if (dictionary.language.empty())
155 continue; 156 continue;
156 157
157 dictionary.used_for_spellcheck = 158 dictionary.used_for_spellcheck =
158 spellcheck_dictionaries.count(dictionary.language) > 0; 159 spellcheck_dictionaries.count(dictionary.language) > 0;
159 dictionaries->push_back(dictionary); 160 dictionaries->push_back(dictionary);
160 } 161 }
161 } 162 }
162 #endif // !OS_MACOSX 163 #endif // !OS_MACOSX
(...skipping 30 matching lines...) Expand all
193 bdict_languages.push_back(SpellCheckBDictLanguage()); 194 bdict_languages.push_back(SpellCheckBDictLanguage());
194 bdict_languages.back().language = hunspell_dictionary->GetLanguage(); 195 bdict_languages.back().language = hunspell_dictionary->GetLanguage();
195 bdict_languages.back().file = 196 bdict_languages.back().file =
196 hunspell_dictionary->GetDictionaryFile().IsValid() 197 hunspell_dictionary->GetDictionaryFile().IsValid()
197 ? IPC::GetPlatformFileForTransit( 198 ? IPC::GetPlatformFileForTransit(
198 hunspell_dictionary->GetDictionaryFile().GetPlatformFile(), 199 hunspell_dictionary->GetDictionaryFile().GetPlatformFile(),
199 false) 200 false)
200 : IPC::InvalidPlatformFileForTransit(); 201 : IPC::InvalidPlatformFileForTransit();
201 } 202 }
202 203
203 bool enabled = prefs->GetBoolean(prefs::kEnableContinuousSpellcheck) && 204 bool enabled = prefs->GetBoolean(spellcheck::prefs::kEnableContinuousSpellchec k) &&
204 !bdict_languages.empty(); 205 !bdict_languages.empty();
205 process->Send(new SpellCheckMsg_Init( 206 process->Send(new SpellCheckMsg_Init(
206 bdict_languages, 207 bdict_languages,
207 enabled ? custom_dictionary_->GetWords() : std::set<std::string>())); 208 enabled ? custom_dictionary_->GetWords() : std::set<std::string>()));
208 process->Send(new SpellCheckMsg_EnableSpellCheck(enabled)); 209 process->Send(new SpellCheckMsg_EnableSpellCheck(enabled));
209 } 210 }
210 211
211 SpellCheckHostMetrics* SpellcheckService::GetMetrics() const { 212 SpellCheckHostMetrics* SpellcheckService::GetMetrics() const {
212 return metrics_.get(); 213 return metrics_.get();
213 } 214 }
214 215
215 SpellcheckCustomDictionary* SpellcheckService::GetCustomDictionary() { 216 SpellcheckCustomDictionary* SpellcheckService::GetCustomDictionary() {
216 return custom_dictionary_.get(); 217 return custom_dictionary_.get();
217 } 218 }
218 219
219 void SpellcheckService::LoadHunspellDictionaries() { 220 void SpellcheckService::LoadHunspellDictionaries() {
220 hunspell_dictionaries_.clear(); 221 hunspell_dictionaries_.clear();
221 222
222 PrefService* prefs = user_prefs::UserPrefs::Get(context_); 223 PrefService* prefs = user_prefs::UserPrefs::Get(context_);
223 DCHECK(prefs); 224 DCHECK(prefs);
224 225
225 const base::ListValue* dictionary_values = 226 const base::ListValue* dictionary_values =
226 prefs->GetList(prefs::kSpellCheckDictionaries); 227 prefs->GetList(spellcheck::prefs::kSpellCheckDictionaries);
227 228
228 for (const auto& dictionary_value : *dictionary_values) { 229 for (const auto& dictionary_value : *dictionary_values) {
229 std::string dictionary; 230 std::string dictionary;
230 dictionary_value->GetAsString(&dictionary); 231 dictionary_value->GetAsString(&dictionary);
231 hunspell_dictionaries_.push_back(new SpellcheckHunspellDictionary( 232 hunspell_dictionaries_.push_back(new SpellcheckHunspellDictionary(
232 dictionary, 233 dictionary,
233 content::BrowserContext::GetDefaultStoragePartition(context_)-> 234 content::BrowserContext::GetDefaultStoragePartition(context_)->
234 GetURLRequestContext(), 235 GetURLRequestContext(),
235 this)); 236 this));
236 hunspell_dictionaries_.back()->AddObserver(this); 237 hunspell_dictionaries_.back()->AddObserver(this);
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
329 UpdateFeedbackSenderState(); 330 UpdateFeedbackSenderState();
330 331
331 // If there are no hunspell dictionaries to load, then immediately let the 332 // If there are no hunspell dictionaries to load, then immediately let the
332 // renderers know the new state. 333 // renderers know the new state.
333 if (hunspell_dictionaries_.empty()) 334 if (hunspell_dictionaries_.empty())
334 InitForAllRenderers(); 335 InitForAllRenderers();
335 } 336 }
336 337
337 void SpellcheckService::OnUseSpellingServiceChanged() { 338 void SpellcheckService::OnUseSpellingServiceChanged() {
338 bool enabled = pref_change_registrar_.prefs()->GetBoolean( 339 bool enabled = pref_change_registrar_.prefs()->GetBoolean(
339 prefs::kSpellCheckUseSpellingService); 340 spellcheck::prefs::kSpellCheckUseSpellingService);
340 if (metrics_) 341 if (metrics_)
341 metrics_->RecordSpellingServiceStats(enabled); 342 metrics_->RecordSpellingServiceStats(enabled);
342 UpdateFeedbackSenderState(); 343 UpdateFeedbackSenderState();
343 } 344 }
344 345
345 void SpellcheckService::OnAcceptLanguagesChanged() { 346 void SpellcheckService::OnAcceptLanguagesChanged() {
346 PrefService* prefs = user_prefs::UserPrefs::Get(context_); 347 PrefService* prefs = user_prefs::UserPrefs::Get(context_);
347 std::vector<std::string> accept_languages = 348 std::vector<std::string> accept_languages =
348 base::SplitString(prefs->GetString(prefs::kAcceptLanguages), ",", 349 base::SplitString(prefs->GetString(prefs::kAcceptLanguages), ",",
349 base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); 350 base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
350 std::transform( 351 std::transform(
351 accept_languages.begin(), accept_languages.end(), 352 accept_languages.begin(), accept_languages.end(),
352 accept_languages.begin(), 353 accept_languages.begin(),
353 &chrome::spellcheck_common::GetCorrespondingSpellCheckLanguage); 354 &spellcheck_common::GetCorrespondingSpellCheckLanguage);
354 355
355 StringListPrefMember dictionaries_pref; 356 StringListPrefMember dictionaries_pref;
356 dictionaries_pref.Init(prefs::kSpellCheckDictionaries, prefs); 357 dictionaries_pref.Init(spellcheck::prefs::kSpellCheckDictionaries, prefs);
357 std::vector<std::string> dictionaries = dictionaries_pref.GetValue(); 358 std::vector<std::string> dictionaries = dictionaries_pref.GetValue();
358 std::vector<std::string> filtered_dictionaries; 359 std::vector<std::string> filtered_dictionaries;
359 360
360 for (const auto& dictionary : dictionaries) { 361 for (const auto& dictionary : dictionaries) {
361 if (std::find(accept_languages.begin(), accept_languages.end(), 362 if (std::find(accept_languages.begin(), accept_languages.end(),
362 dictionary) != accept_languages.end()) { 363 dictionary) != accept_languages.end()) {
363 filtered_dictionaries.push_back(dictionary); 364 filtered_dictionaries.push_back(dictionary);
364 } 365 }
365 } 366 }
366 367
367 dictionaries_pref.SetValue(filtered_dictionaries); 368 dictionaries_pref.SetValue(filtered_dictionaries);
368 } 369 }
369 370
370 void SpellcheckService::UpdateFeedbackSenderState() { 371 void SpellcheckService::UpdateFeedbackSenderState() {
371 std::string feedback_language; 372 std::string feedback_language;
372 if (!hunspell_dictionaries_.empty()) 373 if (!hunspell_dictionaries_.empty())
373 feedback_language = hunspell_dictionaries_.front()->GetLanguage(); 374 feedback_language = hunspell_dictionaries_.front()->GetLanguage();
374 std::string language_code; 375 std::string language_code;
375 std::string country_code; 376 std::string country_code;
376 chrome::spellcheck_common::GetISOLanguageCountryCodeFromLocale( 377 spellcheck_common::GetISOLanguageCountryCodeFromLocale(
377 feedback_language, &language_code, &country_code); 378 feedback_language, &language_code, &country_code);
378 feedback_sender_->OnLanguageCountryChange(language_code, country_code); 379 feedback_sender_->OnLanguageCountryChange(language_code, country_code);
379 if (SpellingServiceClient::IsAvailable( 380 if (SpellingServiceClient::IsAvailable(
380 context_, SpellingServiceClient::SPELLCHECK)) { 381 context_, SpellingServiceClient::SPELLCHECK)) {
381 feedback_sender_->StartFeedbackCollection(); 382 feedback_sender_->StartFeedbackCollection();
382 } else { 383 } else {
383 feedback_sender_->StopFeedbackCollection(); 384 feedback_sender_->StopFeedbackCollection();
384 } 385 }
385 } 386 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698