Chromium Code Reviews| Index: chrome/browser/spellchecker/spellcheck_host_impl.cc |
| diff --git a/chrome/browser/spellchecker/spellcheck_host_impl.cc b/chrome/browser/spellchecker/spellcheck_host_impl.cc |
| index bd184476a51431f16dce9e1f9d2e094e7ae40040..9dcc2b72a1bba10a05aa8ce9ee9f72a0499e4c32 100644 |
| --- a/chrome/browser/spellchecker/spellcheck_host_impl.cc |
| +++ b/chrome/browser/spellchecker/spellcheck_host_impl.cc |
| @@ -6,6 +6,7 @@ |
| #include <set> |
| +#include "base/bind.h" |
| #include "base/file_util.h" |
| #include "base/logging.h" |
| #include "base/path_service.h" |
| @@ -78,6 +79,11 @@ FilePath GetFallbackFilePath(const FilePath& first_choice) { |
| } |
| #endif |
| +void CloseDictionary(base::PlatformFile file) { |
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| + base::ClosePlatformFile(file); |
| +} |
| + |
| } // namespace |
| // Constructed on UI thread. |
| @@ -92,7 +98,8 @@ SpellCheckHostImpl::SpellCheckHostImpl( |
| tried_to_download_(false), |
| use_platform_spellchecker_(false), |
| request_context_getter_(request_context_getter), |
| - metrics_(metrics) { |
| + metrics_(metrics), |
| + weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { |
| DCHECK(profile_); |
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| @@ -101,16 +108,24 @@ SpellCheckHostImpl::SpellCheckHostImpl( |
| custom_dictionary_file_ = |
| personal_file_directory.Append(chrome::kCustomDictionaryFileName); |
| - registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CREATED, |
| + registrar_.Add(weak_ptr_factory_.GetWeakPtr(), |
| + content::NOTIFICATION_RENDERER_PROCESS_CREATED, |
| content::NotificationService::AllSources()); |
| } |
| SpellCheckHostImpl::~SpellCheckHostImpl() { |
| - if (file_ != base::kInvalidPlatformFileValue) |
| - base::ClosePlatformFile(file_); |
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| + |
| + if (file_ != base::kInvalidPlatformFileValue) { |
| + BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, |
| + base::Bind(&CloseDictionary, file_)); |
| + file_ = base::kInvalidPlatformFileValue; |
| + } |
| } |
| void SpellCheckHostImpl::Initialize() { |
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| + |
| if (SpellCheckerPlatform::SpellCheckerAvailable() && |
| SpellCheckerPlatform::PlatformSupportsLanguage(language_)) { |
| #if defined(OS_MACOSX) |
| @@ -119,8 +134,8 @@ void SpellCheckHostImpl::Initialize() { |
| use_platform_spellchecker_ = true; |
| SpellCheckerPlatform::SetLanguage(language_); |
| MessageLoop::current()->PostTask(FROM_HERE, |
| - NewRunnableMethod(this, |
| - &SpellCheckHostImpl::InformProfileOfInitialization)); |
| + base::Bind(&SpellCheckHostImpl::InformProfileOfInitialization, |
| + weak_ptr_factory_.GetWeakPtr())); |
| return; |
| } |
| @@ -128,9 +143,11 @@ void SpellCheckHostImpl::Initialize() { |
| RecordSpellCheckStats(false, language_); |
| #endif |
| - BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, |
| - NewRunnableMethod(this, |
| - &SpellCheckHostImpl::InitializeDictionaryLocation)); |
| + BrowserThread::PostTaskAndReply(BrowserThread::FILE, FROM_HERE, |
| + base::Bind(&SpellCheckHostImpl::InitializeDictionaryLocation, |
| + base::Unretained(this)), |
| + base::Bind(&SpellCheckHostImpl::InitializeDictionaryLocationComplete, |
| + weak_ptr_factory_.GetWeakPtr())); |
| } |
| void SpellCheckHostImpl::UnsetProfile() { |
| @@ -175,13 +192,12 @@ void SpellCheckHostImpl::AddWord(const std::string& word) { |
| if (profile_) |
| profile_->CustomWordAddedLocally(word); |
| - BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, |
| - NewRunnableMethod(this, |
| - &SpellCheckHostImpl::WriteWordToCustomDictionary, word)); |
| - for (RenderProcessHost::iterator i(RenderProcessHost::AllHostsIterator()); |
| - !i.IsAtEnd(); i.Advance()) { |
| - i.GetCurrentValue()->Send(new SpellCheckMsg_WordAdded(word)); |
| - } |
| + |
| + BrowserThread::PostTaskAndReply(BrowserThread::FILE, FROM_HERE, |
| + base::Bind(&SpellCheckHostImpl::WriteWordToCustomDictionary, |
| + base::Unretained(this), word), |
| + base::Bind(&SpellCheckHostImpl::AddWordComplete, |
| + weak_ptr_factory_.GetWeakPtr(), word)); |
| } |
| void SpellCheckHostImpl::InitializeDictionaryLocation() { |
| @@ -202,12 +218,6 @@ void SpellCheckHostImpl::InitializeDictionaryLocation() { |
| } |
| #endif |
| - InitializeInternal(); |
| -} |
| - |
| -void SpellCheckHostImpl::InitializeInternal() { |
| - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| - |
| if (!profile_) |
| return; |
| @@ -229,31 +239,33 @@ void SpellCheckHostImpl::InitializeInternal() { |
| // File didn't exist. Download it. |
| if (file_ == base::kInvalidPlatformFileValue && !tried_to_download_ && |
| request_context_getter_) { |
| - // We download from the ui thread because we need to know that |
| - // |request_context_getter_| is still valid before initiating the download. |
| - BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
| - NewRunnableMethod(this, &SpellCheckHostImpl::DownloadDictionary)); |
| + // Return this function so InitializeDictionaryLocationComplete() can start |
| + // downloading the dictionary. |
| return; |
| } |
| request_context_getter_ = NULL; |
| - scoped_ptr<CustomWordList> custom_words(new CustomWordList()); |
| + custom_words_.reset(new CustomWordList()); |
| if (file_ != base::kInvalidPlatformFileValue) |
| - LoadCustomDictionary(custom_words.get()); |
| - |
| - BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
| - NewRunnableMethod( |
| - this, |
| - &SpellCheckHostImpl::InformProfileOfInitializationWithCustomWords, |
| - custom_words.release())); |
| + LoadCustomDictionary(custom_words_.get()); |
| } |
| -void SpellCheckHostImpl::InitializeOnFileThread() { |
| - DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| - |
| - BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, |
| - NewRunnableMethod(this, &SpellCheckHostImpl::Initialize)); |
| +void SpellCheckHostImpl::InitializeDictionaryLocationComplete() { |
| + if (file_ == base::kInvalidPlatformFileValue && !tried_to_download_ && |
| + request_context_getter_) { |
| + // We download from the ui thread because we need to know that |
| + // |request_context_getter_| is still valid before initiating the download. |
| + BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
| + base::Bind(&SpellCheckHostImpl::DownloadDictionary, |
| + weak_ptr_factory_.GetWeakPtr())); |
| + } else { |
| + BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
| + base::Bind( |
| + &SpellCheckHostImpl::InformProfileOfInitializationWithCustomWords, |
| + weak_ptr_factory_.GetWeakPtr(), |
| + custom_words_.release())); |
| + } |
| } |
| void SpellCheckHostImpl::InformProfileOfInitialization() { |
| @@ -280,11 +292,7 @@ void SpellCheckHostImpl::InformProfileOfInitializationWithCustomWords( |
| void SpellCheckHostImpl::DownloadDictionary() { |
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| - |
| - if (!request_context_getter_) { |
| - InitializeOnFileThread(); |
| - return; |
| - } |
| + DCHECK(request_context_getter_); |
| // Determine URL of file to download. |
| static const char kDownloadServerUrl[] = |
| @@ -296,8 +304,8 @@ void SpellCheckHostImpl::DownloadDictionary() { |
| } |
| GURL url = GURL(std::string(kDownloadServerUrl) + |
| StringToLowerASCII(bdict_file)); |
| - fetcher_.reset(content::URLFetcher::Create( |
| - url, content::URLFetcher::GET, this)); |
| + fetcher_.reset(content::URLFetcher::Create(url, content::URLFetcher::GET, |
| + weak_ptr_factory_.GetWeakPtr())); |
| fetcher_->SetRequestContext(request_context_getter_); |
| tried_to_download_ = true; |
| fetcher_->Start(); |
| @@ -341,7 +349,6 @@ void SpellCheckHostImpl::OnURLFetchComplete(const content::URLFetcher* source) { |
| if ((source->GetResponseCode() / 100) != 2) { |
| // Initialize will not try to download the file a second time. |
| LOG(ERROR) << "Failure to download dictionary."; |
| - InitializeOnFileThread(); |
| return; |
| } |
| @@ -353,13 +360,15 @@ void SpellCheckHostImpl::OnURLFetchComplete(const content::URLFetcher* source) { |
| if (data.size() < 4 || data[0] != 'B' || data[1] != 'D' || data[2] != 'i' || |
| data[3] != 'c') { |
| LOG(ERROR) << "Failure to download dictionary."; |
| - InitializeOnFileThread(); |
| return; |
| } |
| data_ = data; |
| - BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, |
| - NewRunnableMethod(this, &SpellCheckHostImpl::SaveDictionaryData)); |
| + BrowserThread::PostTaskAndReply(BrowserThread::FILE, FROM_HERE, |
| + base::Bind(&SpellCheckHostImpl::SaveDictionaryData, |
| + base::Unretained(this)), |
| + base::Bind(&SpellCheckHostImpl::InformProfileOfInitialization, |
| + weak_ptr_factory_.GetWeakPtr())); |
| } |
| void SpellCheckHostImpl::Observe(int type, |
| @@ -380,9 +389,7 @@ void SpellCheckHostImpl::SaveDictionaryData() { |
| metrics_->RecordDictionaryCorruptionStats(!verified); |
| if (!verified) { |
| LOG(ERROR) << "Failure to verify the downloaded dictionary."; |
| - BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
| - NewRunnableMethod(this, |
| - &SpellCheckHostImpl::InformProfileOfInitialization)); |
| + // Let PostTaskAndReply caller send to InformProfileOfInitialization |
| return; |
| } |
| @@ -404,15 +411,14 @@ void SpellCheckHostImpl::SaveDictionaryData() { |
| LOG(ERROR) << "Failure to save dictionary."; |
| file_util::Delete(bdict_file_path_, false); |
| // To avoid trying to load a partially saved dictionary, shortcut the |
| - // Initialize() call. |
| - BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
| - NewRunnableMethod(this, |
| - &SpellCheckHostImpl::InformProfileOfInitialization)); |
| + // Initialize() call. Let PostTaskAndReply caller send to |
| + // InformProfileOfInitialization. |
| return; |
| } |
| } |
| data_.clear(); |
| + |
|
Hironori Bono
2011/11/04 03:46:59
nit: sorry, I forgot answering your question why w
|
| Initialize(); |
| } |
| @@ -450,3 +456,12 @@ const std::string& SpellCheckHostImpl::GetLanguage() const { |
| bool SpellCheckHostImpl::IsUsingPlatformChecker() const { |
| return use_platform_spellchecker_; |
| } |
| + |
| +void SpellCheckHostImpl::AddWordComplete(const std::string& word) { |
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| + |
| + for (RenderProcessHost::iterator i(RenderProcessHost::AllHostsIterator()); |
| + !i.IsAtEnd(); i.Advance()) { |
| + i.GetCurrentValue()->Send(new SpellCheckMsg_WordAdded(word)); |
| + } |
| +} |