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

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

Issue 8432027: NOT FOR REVIEW: quick hacks for http://codereview.chromium.org/7919003/ Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 9 years, 1 month 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 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 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_host_impl.h" 5 #include "chrome/browser/spellchecker/spellcheck_host_impl.h"
6 6
7 #include <set> 7 #include <set>
8 8
9 #include "base/bind.h"
9 #include "base/file_util.h" 10 #include "base/file_util.h"
10 #include "base/logging.h" 11 #include "base/logging.h"
11 #include "base/path_service.h" 12 #include "base/path_service.h"
12 #include "base/string_split.h" 13 #include "base/string_split.h"
13 #include "base/threading/thread_restrictions.h" 14 #include "base/threading/thread_restrictions.h"
14 #include "base/utf_string_conversions.h" 15 #include "base/utf_string_conversions.h"
15 #include "chrome/browser/prefs/pref_service.h" 16 #include "chrome/browser/prefs/pref_service.h"
16 #include "chrome/browser/profiles/profile.h" 17 #include "chrome/browser/profiles/profile.h"
17 #include "chrome/browser/spellchecker/spellcheck_host_metrics.h" 18 #include "chrome/browser/spellchecker/spellcheck_host_metrics.h"
18 #include "chrome/browser/spellchecker/spellcheck_profile_provider.h" 19 #include "chrome/browser/spellchecker/spellcheck_profile_provider.h"
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
71 #endif 72 #endif
72 73
73 #if defined(OS_WIN) 74 #if defined(OS_WIN)
74 FilePath GetFallbackFilePath(const FilePath& first_choice) { 75 FilePath GetFallbackFilePath(const FilePath& first_choice) {
75 FilePath dict_dir; 76 FilePath dict_dir;
76 PathService::Get(chrome::DIR_USER_DATA, &dict_dir); 77 PathService::Get(chrome::DIR_USER_DATA, &dict_dir);
77 return dict_dir.Append(first_choice.BaseName()); 78 return dict_dir.Append(first_choice.BaseName());
78 } 79 }
79 #endif 80 #endif
80 81
82 void CloseDictionary(base::PlatformFile file) {
83 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
84 base::ClosePlatformFile(file);
85 }
86
81 } // namespace 87 } // namespace
82 88
83 // Constructed on UI thread. 89 // Constructed on UI thread.
84 SpellCheckHostImpl::SpellCheckHostImpl( 90 SpellCheckHostImpl::SpellCheckHostImpl(
85 SpellCheckProfileProvider* profile, 91 SpellCheckProfileProvider* profile,
86 const std::string& language, 92 const std::string& language,
87 net::URLRequestContextGetter* request_context_getter, 93 net::URLRequestContextGetter* request_context_getter,
88 SpellCheckHostMetrics* metrics) 94 SpellCheckHostMetrics* metrics)
89 : profile_(profile), 95 : profile_(profile),
90 language_(language), 96 language_(language),
91 file_(base::kInvalidPlatformFileValue), 97 file_(base::kInvalidPlatformFileValue),
92 tried_to_download_(false), 98 tried_to_download_(false),
93 use_platform_spellchecker_(false), 99 use_platform_spellchecker_(false),
94 request_context_getter_(request_context_getter), 100 request_context_getter_(request_context_getter),
95 metrics_(metrics) { 101 metrics_(metrics),
102 weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
96 DCHECK(profile_); 103 DCHECK(profile_);
97 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 104 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
98 105
99 FilePath personal_file_directory; 106 FilePath personal_file_directory;
100 PathService::Get(chrome::DIR_USER_DATA, &personal_file_directory); 107 PathService::Get(chrome::DIR_USER_DATA, &personal_file_directory);
101 custom_dictionary_file_ = 108 custom_dictionary_file_ =
102 personal_file_directory.Append(chrome::kCustomDictionaryFileName); 109 personal_file_directory.Append(chrome::kCustomDictionaryFileName);
103 110
104 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CREATED, 111 registrar_.Add(weak_ptr_factory_.GetWeakPtr(),
112 content::NOTIFICATION_RENDERER_PROCESS_CREATED,
105 content::NotificationService::AllSources()); 113 content::NotificationService::AllSources());
106 } 114 }
107 115
108 SpellCheckHostImpl::~SpellCheckHostImpl() { 116 SpellCheckHostImpl::~SpellCheckHostImpl() {
109 if (file_ != base::kInvalidPlatformFileValue) 117 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
110 base::ClosePlatformFile(file_); 118
119 if (file_ != base::kInvalidPlatformFileValue) {
120 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
121 base::Bind(&CloseDictionary, file_));
122 file_ = base::kInvalidPlatformFileValue;
123 }
111 } 124 }
112 125
113 void SpellCheckHostImpl::Initialize() { 126 void SpellCheckHostImpl::Initialize() {
127 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
128
114 if (SpellCheckerPlatform::SpellCheckerAvailable() && 129 if (SpellCheckerPlatform::SpellCheckerAvailable() &&
115 SpellCheckerPlatform::PlatformSupportsLanguage(language_)) { 130 SpellCheckerPlatform::PlatformSupportsLanguage(language_)) {
116 #if defined(OS_MACOSX) 131 #if defined(OS_MACOSX)
117 RecordSpellCheckStats(true, language_); 132 RecordSpellCheckStats(true, language_);
118 #endif 133 #endif
119 use_platform_spellchecker_ = true; 134 use_platform_spellchecker_ = true;
120 SpellCheckerPlatform::SetLanguage(language_); 135 SpellCheckerPlatform::SetLanguage(language_);
121 MessageLoop::current()->PostTask(FROM_HERE, 136 MessageLoop::current()->PostTask(FROM_HERE,
122 NewRunnableMethod(this, 137 base::Bind(&SpellCheckHostImpl::InformProfileOfInitialization,
123 &SpellCheckHostImpl::InformProfileOfInitialization)); 138 weak_ptr_factory_.GetWeakPtr()));
124 return; 139 return;
125 } 140 }
126 141
127 #if defined(OS_MACOSX) 142 #if defined(OS_MACOSX)
128 RecordSpellCheckStats(false, language_); 143 RecordSpellCheckStats(false, language_);
129 #endif 144 #endif
130 145
131 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, 146 BrowserThread::PostTaskAndReply(BrowserThread::FILE, FROM_HERE,
132 NewRunnableMethod(this, 147 base::Bind(&SpellCheckHostImpl::InitializeDictionaryLocation,
133 &SpellCheckHostImpl::InitializeDictionaryLocation)); 148 base::Unretained(this)),
149 base::Bind(&SpellCheckHostImpl::InitializeDictionaryLocationComplete,
150 weak_ptr_factory_.GetWeakPtr()));
134 } 151 }
135 152
136 void SpellCheckHostImpl::UnsetProfile() { 153 void SpellCheckHostImpl::UnsetProfile() {
137 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 154 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
138 155
139 profile_ = NULL; 156 profile_ = NULL;
140 request_context_getter_ = NULL; 157 request_context_getter_ = NULL;
141 fetcher_.reset(); 158 fetcher_.reset();
142 registrar_.RemoveAll(); 159 registrar_.RemoveAll();
143 } 160 }
(...skipping 24 matching lines...) Expand all
168 profile_ ? profile_->GetCustomWords() : CustomWordList(), 185 profile_ ? profile_->GetCustomWords() : CustomWordList(),
169 GetLanguage(), 186 GetLanguage(),
170 prefs->GetBoolean(prefs::kEnableAutoSpellCorrect))); 187 prefs->GetBoolean(prefs::kEnableAutoSpellCorrect)));
171 } 188 }
172 189
173 void SpellCheckHostImpl::AddWord(const std::string& word) { 190 void SpellCheckHostImpl::AddWord(const std::string& word) {
174 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 191 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
175 192
176 if (profile_) 193 if (profile_)
177 profile_->CustomWordAddedLocally(word); 194 profile_->CustomWordAddedLocally(word);
178 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, 195
179 NewRunnableMethod(this, 196 BrowserThread::PostTaskAndReply(BrowserThread::FILE, FROM_HERE,
180 &SpellCheckHostImpl::WriteWordToCustomDictionary, word)); 197 base::Bind(&SpellCheckHostImpl::WriteWordToCustomDictionary,
181 for (RenderProcessHost::iterator i(RenderProcessHost::AllHostsIterator()); 198 base::Unretained(this), word),
182 !i.IsAtEnd(); i.Advance()) { 199 base::Bind(&SpellCheckHostImpl::AddWordComplete,
183 i.GetCurrentValue()->Send(new SpellCheckMsg_WordAdded(word)); 200 weak_ptr_factory_.GetWeakPtr(), word));
184 }
185 } 201 }
186 202
187 void SpellCheckHostImpl::InitializeDictionaryLocation() { 203 void SpellCheckHostImpl::InitializeDictionaryLocation() {
188 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 204 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
189 205
190 // Initialize the BDICT path. This initialization should be in the FILE thread 206 // Initialize the BDICT path. This initialization should be in the FILE thread
191 // because it checks if there is a "Dictionaries" directory and create it. 207 // because it checks if there is a "Dictionaries" directory and create it.
192 if (bdict_file_path_.empty()) 208 if (bdict_file_path_.empty())
193 bdict_file_path_ = GetFirstChoiceFilePath(language_); 209 bdict_file_path_ = GetFirstChoiceFilePath(language_);
194 210
195 #if defined(OS_WIN) 211 #if defined(OS_WIN)
196 // Check if the dictionary exists in the fallback location. If so, use it 212 // Check if the dictionary exists in the fallback location. If so, use it
197 // rather than downloading anew. 213 // rather than downloading anew.
198 FilePath fallback = GetFallbackFilePath(bdict_file_path_); 214 FilePath fallback = GetFallbackFilePath(bdict_file_path_);
199 if (!file_util::PathExists(bdict_file_path_) && 215 if (!file_util::PathExists(bdict_file_path_) &&
200 file_util::PathExists(fallback)) { 216 file_util::PathExists(fallback)) {
201 bdict_file_path_ = fallback; 217 bdict_file_path_ = fallback;
202 } 218 }
203 #endif 219 #endif
204 220
205 InitializeInternal();
206 }
207
208 void SpellCheckHostImpl::InitializeInternal() {
209 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
210
211 if (!profile_) 221 if (!profile_)
212 return; 222 return;
213 223
214 if (!VerifyBDict(bdict_file_path_)) { 224 if (!VerifyBDict(bdict_file_path_)) {
215 DCHECK_EQ(file_, base::kInvalidPlatformFileValue); 225 DCHECK_EQ(file_, base::kInvalidPlatformFileValue);
216 file_util::Delete(bdict_file_path_, false); 226 file_util::Delete(bdict_file_path_, false);
217 227
218 // Notify browser tests that this dictionary is corrupted. We also skip 228 // Notify browser tests that this dictionary is corrupted. We also skip
219 // downloading the dictionary when we run this function on browser tests. 229 // downloading the dictionary when we run this function on browser tests.
220 if (SignalStatusEvent(BDICT_CORRUPTED)) 230 if (SignalStatusEvent(BDICT_CORRUPTED))
221 tried_to_download_ = true; 231 tried_to_download_ = true;
222 } else { 232 } else {
223 file_ = base::CreatePlatformFile( 233 file_ = base::CreatePlatformFile(
224 bdict_file_path_, 234 bdict_file_path_,
225 base::PLATFORM_FILE_READ | base::PLATFORM_FILE_OPEN, 235 base::PLATFORM_FILE_READ | base::PLATFORM_FILE_OPEN,
226 NULL, NULL); 236 NULL, NULL);
227 } 237 }
228 238
229 // File didn't exist. Download it. 239 // File didn't exist. Download it.
230 if (file_ == base::kInvalidPlatformFileValue && !tried_to_download_ && 240 if (file_ == base::kInvalidPlatformFileValue && !tried_to_download_ &&
231 request_context_getter_) { 241 request_context_getter_) {
242 // Return this function so InitializeDictionaryLocationComplete() can start
243 // downloading the dictionary.
244 return;
245 }
246
247 request_context_getter_ = NULL;
248
249 custom_words_.reset(new CustomWordList());
250 if (file_ != base::kInvalidPlatformFileValue)
251 LoadCustomDictionary(custom_words_.get());
252 }
253
254 void SpellCheckHostImpl::InitializeDictionaryLocationComplete() {
255 if (file_ == base::kInvalidPlatformFileValue && !tried_to_download_ &&
256 request_context_getter_) {
232 // We download from the ui thread because we need to know that 257 // We download from the ui thread because we need to know that
233 // |request_context_getter_| is still valid before initiating the download. 258 // |request_context_getter_| is still valid before initiating the download.
234 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 259 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
235 NewRunnableMethod(this, &SpellCheckHostImpl::DownloadDictionary)); 260 base::Bind(&SpellCheckHostImpl::DownloadDictionary,
236 return; 261 weak_ptr_factory_.GetWeakPtr()));
262 } else {
263 // TODO: This could be a reply point for the calling PostTaskAndReply().
264 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
265 base::Bind(
266 &SpellCheckHostImpl::InformProfileOfInitializationWithCustomWords,
267 weak_ptr_factory_.GetWeakPtr(),
268 custom_words_.release()));
237 } 269 }
238
239 request_context_getter_ = NULL;
240
241 scoped_ptr<CustomWordList> custom_words(new CustomWordList());
242 if (file_ != base::kInvalidPlatformFileValue)
243 LoadCustomDictionary(custom_words.get());
244
245 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
246 NewRunnableMethod(
247 this,
248 &SpellCheckHostImpl::InformProfileOfInitializationWithCustomWords,
249 custom_words.release()));
250 }
251
252 void SpellCheckHostImpl::InitializeOnFileThread() {
253 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::FILE));
254
255 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
256 NewRunnableMethod(this, &SpellCheckHostImpl::Initialize));
257 } 270 }
258 271
259 void SpellCheckHostImpl::InformProfileOfInitialization() { 272 void SpellCheckHostImpl::InformProfileOfInitialization() {
260 InformProfileOfInitializationWithCustomWords(NULL); 273 InformProfileOfInitializationWithCustomWords(NULL);
261 } 274 }
262 275
263 void SpellCheckHostImpl::InformProfileOfInitializationWithCustomWords( 276 void SpellCheckHostImpl::InformProfileOfInitializationWithCustomWords(
264 CustomWordList* custom_words) { 277 CustomWordList* custom_words) {
265 // Non-null |custom_words| should be given only if the profile is available 278 // Non-null |custom_words| should be given only if the profile is available
266 // for simplifying the life-cycle management of the word list. 279 // for simplifying the life-cycle management of the word list.
267 DCHECK(profile_ || !custom_words); 280 DCHECK(profile_ || !custom_words);
268 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 281 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
269 282
270 if (profile_) 283 if (profile_)
271 profile_->SpellCheckHostInitialized(custom_words); 284 profile_->SpellCheckHostInitialized(custom_words);
272 285
273 for (RenderProcessHost::iterator i(RenderProcessHost::AllHostsIterator()); 286 for (RenderProcessHost::iterator i(RenderProcessHost::AllHostsIterator());
274 !i.IsAtEnd(); i.Advance()) { 287 !i.IsAtEnd(); i.Advance()) {
275 RenderProcessHost* process = i.GetCurrentValue(); 288 RenderProcessHost* process = i.GetCurrentValue();
276 if (process) 289 if (process)
277 InitForRenderer(process); 290 InitForRenderer(process);
278 } 291 }
279 } 292 }
280 293
281 void SpellCheckHostImpl::DownloadDictionary() { 294 void SpellCheckHostImpl::DownloadDictionary() {
282 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 295 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
283 296 DCHECK(request_context_getter_);
284 if (!request_context_getter_) {
285 InitializeOnFileThread();
286 return;
287 }
288 297
289 // Determine URL of file to download. 298 // Determine URL of file to download.
290 static const char kDownloadServerUrl[] = 299 static const char kDownloadServerUrl[] =
291 "http://cache.pack.google.com/edgedl/chrome/dict/"; 300 "http://cache.pack.google.com/edgedl/chrome/dict/";
292 std::string bdict_file = bdict_file_path_.BaseName().MaybeAsASCII(); 301 std::string bdict_file = bdict_file_path_.BaseName().MaybeAsASCII();
293 if (bdict_file.empty()) { 302 if (bdict_file.empty()) {
294 NOTREACHED(); 303 NOTREACHED();
295 return; 304 return;
296 } 305 }
297 GURL url = GURL(std::string(kDownloadServerUrl) + 306 GURL url = GURL(std::string(kDownloadServerUrl) +
298 StringToLowerASCII(bdict_file)); 307 StringToLowerASCII(bdict_file));
299 fetcher_.reset(content::URLFetcher::Create( 308 fetcher_.reset(content::URLFetcher::Create(url, content::URLFetcher::GET,
300 url, content::URLFetcher::GET, this)); 309 weak_ptr_factory_.GetWeakPtr()));
301 fetcher_->SetRequestContext(request_context_getter_); 310 fetcher_->SetRequestContext(request_context_getter_);
302 tried_to_download_ = true; 311 tried_to_download_ = true;
303 fetcher_->Start(); 312 fetcher_->Start();
304 request_context_getter_ = NULL; 313 request_context_getter_ = NULL;
305 } 314 }
306 315
307 void SpellCheckHostImpl::LoadCustomDictionary(CustomWordList* custom_words) { 316 void SpellCheckHostImpl::LoadCustomDictionary(CustomWordList* custom_words) {
308 if (!custom_words) 317 if (!custom_words)
309 return; 318 return;
310 319
(...skipping 23 matching lines...) Expand all
334 } 343 }
335 344
336 void SpellCheckHostImpl::OnURLFetchComplete(const content::URLFetcher* source) { 345 void SpellCheckHostImpl::OnURLFetchComplete(const content::URLFetcher* source) {
337 DCHECK(source); 346 DCHECK(source);
338 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 347 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
339 scoped_ptr<content::URLFetcher> fetcher_destructor(fetcher_.release()); 348 scoped_ptr<content::URLFetcher> fetcher_destructor(fetcher_.release());
340 349
341 if ((source->GetResponseCode() / 100) != 2) { 350 if ((source->GetResponseCode() / 100) != 2) {
342 // Initialize will not try to download the file a second time. 351 // Initialize will not try to download the file a second time.
343 LOG(ERROR) << "Failure to download dictionary."; 352 LOG(ERROR) << "Failure to download dictionary.";
344 InitializeOnFileThread();
345 return; 353 return;
346 } 354 }
347 355
348 // Basic sanity check on the dictionary. 356 // Basic sanity check on the dictionary.
349 // There's the small chance that we might see a 200 status code for a body 357 // There's the small chance that we might see a 200 status code for a body
350 // that represents some form of failure. 358 // that represents some form of failure.
351 std::string data; 359 std::string data;
352 source->GetResponseAsString(&data); 360 source->GetResponseAsString(&data);
353 if (data.size() < 4 || data[0] != 'B' || data[1] != 'D' || data[2] != 'i' || 361 if (data.size() < 4 || data[0] != 'B' || data[1] != 'D' || data[2] != 'i' ||
354 data[3] != 'c') { 362 data[3] != 'c') {
355 LOG(ERROR) << "Failure to download dictionary."; 363 LOG(ERROR) << "Failure to download dictionary.";
356 InitializeOnFileThread();
357 return; 364 return;
358 } 365 }
359 366
360 data_ = data; 367 data_ = data;
361 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, 368 BrowserThread::PostTaskAndReply(BrowserThread::FILE, FROM_HERE,
362 NewRunnableMethod(this, &SpellCheckHostImpl::SaveDictionaryData)); 369 base::Bind(&SpellCheckHostImpl::SaveDictionaryData,
370 base::Unretained(this)),
371 base::Bind(&SpellCheckHostImpl::InformProfileOfInitialization,
372 weak_ptr_factory_.GetWeakPtr()));
363 } 373 }
364 374
365 void SpellCheckHostImpl::Observe(int type, 375 void SpellCheckHostImpl::Observe(int type,
366 const content::NotificationSource& source, 376 const content::NotificationSource& source,
367 const content::NotificationDetails& details) { 377 const content::NotificationDetails& details) {
368 DCHECK(type == content::NOTIFICATION_RENDERER_PROCESS_CREATED); 378 DCHECK(type == content::NOTIFICATION_RENDERER_PROCESS_CREATED);
369 RenderProcessHost* process = content::Source<RenderProcessHost>(source).ptr(); 379 RenderProcessHost* process = content::Source<RenderProcessHost>(source).ptr();
370 InitForRenderer(process); 380 InitForRenderer(process);
371 } 381 }
372 382
373 void SpellCheckHostImpl::SaveDictionaryData() { 383 void SpellCheckHostImpl::SaveDictionaryData() {
374 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 384 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
375 385
376 // To prevent corrupted dictionary data from causing a renderer crash, scan 386 // To prevent corrupted dictionary data from causing a renderer crash, scan
377 // the dictionary data and verify it is sane before save it to a file. 387 // the dictionary data and verify it is sane before save it to a file.
378 bool verified = hunspell::BDict::Verify(data_.data(), data_.size()); 388 bool verified = hunspell::BDict::Verify(data_.data(), data_.size());
379 if (metrics_) 389 if (metrics_)
380 metrics_->RecordDictionaryCorruptionStats(!verified); 390 metrics_->RecordDictionaryCorruptionStats(!verified);
381 if (!verified) { 391 if (!verified) {
382 LOG(ERROR) << "Failure to verify the downloaded dictionary."; 392 LOG(ERROR) << "Failure to verify the downloaded dictionary.";
383 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 393 // Let PostTaskAndReply caller send to InformProfileOfInitialization
384 NewRunnableMethod(this,
385 &SpellCheckHostImpl::InformProfileOfInitialization));
386 return; 394 return;
387 } 395 }
388 396
389 size_t bytes_written = 397 size_t bytes_written =
390 file_util::WriteFile(bdict_file_path_, data_.data(), data_.length()); 398 file_util::WriteFile(bdict_file_path_, data_.data(), data_.length());
391 if (bytes_written != data_.length()) { 399 if (bytes_written != data_.length()) {
392 bool success = false; 400 bool success = false;
393 #if defined(OS_WIN) 401 #if defined(OS_WIN)
394 bdict_file_path_ = GetFallbackFilePath(bdict_file_path_); 402 bdict_file_path_ = GetFallbackFilePath(bdict_file_path_);
395 bytes_written = 403 bytes_written =
396 file_util::WriteFile(GetFallbackFilePath(bdict_file_path_), 404 file_util::WriteFile(GetFallbackFilePath(bdict_file_path_),
397 data_.data(), data_.length()); 405 data_.data(), data_.length());
398 if (bytes_written == data_.length()) 406 if (bytes_written == data_.length())
399 success = true; 407 success = true;
400 #endif 408 #endif
401 data_.clear(); 409 data_.clear();
402 410
403 if (!success) { 411 if (!success) {
404 LOG(ERROR) << "Failure to save dictionary."; 412 LOG(ERROR) << "Failure to save dictionary.";
405 file_util::Delete(bdict_file_path_, false); 413 file_util::Delete(bdict_file_path_, false);
406 // To avoid trying to load a partially saved dictionary, shortcut the 414 // To avoid trying to load a partially saved dictionary, shortcut the
407 // Initialize() call. 415 // Initialize() call. Let PostTaskAndReply caller send to
408 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 416 // InformProfileOfInitialization.
409 NewRunnableMethod(this,
410 &SpellCheckHostImpl::InformProfileOfInitialization));
411 return; 417 return;
412 } 418 }
413 } 419 }
414 420
415 data_.clear(); 421 data_.clear();
422
423 // TODO: Bubble out Initialize() so it's not butchered.
424 // Why isn't this all built up with the contructor? Does it
425 // need to occur like this? Can the FILE and UI uses of
426 // Initialized be separated better?
416 Initialize(); 427 Initialize();
417 } 428 }
418 429
419 bool SpellCheckHostImpl::VerifyBDict(const FilePath& path) const { 430 bool SpellCheckHostImpl::VerifyBDict(const FilePath& path) const {
420 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 431 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
421 432
422 // Read the dictionary file and scan its data. We need to close this file 433 // Read the dictionary file and scan its data. We need to close this file
423 // after scanning its data so we can delete it and download a new dictionary 434 // after scanning its data so we can delete it and download a new dictionary
424 // from our dictionary-download server if it is corrupted. 435 // from our dictionary-download server if it is corrupted.
425 file_util::MemoryMappedFile map; 436 file_util::MemoryMappedFile map;
(...skipping 17 matching lines...) Expand all
443 return file_; 454 return file_;
444 } 455 }
445 456
446 const std::string& SpellCheckHostImpl::GetLanguage() const { 457 const std::string& SpellCheckHostImpl::GetLanguage() const {
447 return language_; 458 return language_;
448 } 459 }
449 460
450 bool SpellCheckHostImpl::IsUsingPlatformChecker() const { 461 bool SpellCheckHostImpl::IsUsingPlatformChecker() const {
451 return use_platform_spellchecker_; 462 return use_platform_spellchecker_;
452 } 463 }
464
465 void SpellCheckHostImpl::AddWordComplete(const std::string& word) {
466 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
467
468 for (RenderProcessHost::iterator i(RenderProcessHost::AllHostsIterator());
469 !i.IsAtEnd(); i.Advance()) {
470 i.GetCurrentValue()->Send(new SpellCheckMsg_WordAdded(word));
471 }
472 }
OLDNEW
« no previous file with comments | « chrome/browser/spellchecker/spellcheck_host_impl.h ('k') | chrome/browser/spellchecker/spellcheck_profile.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698