| Index: chrome/browser/spellcheck_host.cc
|
| ===================================================================
|
| --- chrome/browser/spellcheck_host.cc (revision 31826)
|
| +++ chrome/browser/spellcheck_host.cc (working copy)
|
| @@ -121,6 +121,18 @@
|
| return dict_dir.AppendASCII(versioned_bdict_file_name);
|
| }
|
|
|
| +FilePath GetFirstChoiceFilePath(const std::string& language) {
|
| + FilePath dict_dir;
|
| + PathService::Get(chrome::DIR_APP_DICTIONARIES, &dict_dir);
|
| + return GetVersionedFileName(language, dict_dir);
|
| +}
|
| +
|
| +FilePath GetFallbackFilePath(const FilePath& first_choice) {
|
| + FilePath dict_dir;
|
| + PathService::Get(chrome::DIR_USER_DATA, &dict_dir);
|
| + return dict_dir.Append(first_choice.BaseName());
|
| +}
|
| +
|
| } // namespace
|
|
|
| // Constructed on UI thread.
|
| @@ -129,29 +141,26 @@
|
| URLRequestContextGetter* request_context_getter)
|
| : observer_(observer),
|
| language_(language),
|
| + file_(base::kInvalidPlatformFileValue),
|
| tried_to_download_(false),
|
| request_context_getter_(request_context_getter) {
|
| DCHECK(observer_);
|
| DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
|
|
|
| - // TODO(estade): for Windows, we need to fall back to DIR_USER_DATA if
|
| - // DIR_APP_DICTIONARIES is not writeable.
|
| - FilePath dict_dir;
|
| - PathService::Get(chrome::DIR_APP_DICTIONARIES, &dict_dir);
|
| - bdict_file_ = GetVersionedFileName(language, dict_dir);
|
| -
|
| FilePath personal_file_directory;
|
| PathService::Get(chrome::DIR_USER_DATA, &personal_file_directory);
|
| custom_dictionary_file_ =
|
| personal_file_directory.Append(chrome::kCustomDictionaryFileName);
|
|
|
| + bdict_file_path_ = GetFirstChoiceFilePath(language);
|
| +
|
| ChromeThread::PostTask(ChromeThread::FILE, FROM_HERE,
|
| - NewRunnableMethod(this, &SpellCheckHost::Initialize));
|
| + NewRunnableMethod(this, &SpellCheckHost::InitializeDictionaryLocation));
|
| }
|
|
|
| SpellCheckHost::~SpellCheckHost() {
|
| - if (fd_.fd != -1)
|
| - close(fd_.fd);
|
| + if (file_ != base::kInvalidPlatformFileValue)
|
| + base::ClosePlatformFile(file_);
|
| }
|
|
|
| void SpellCheckHost::UnsetObserver() {
|
| @@ -172,24 +181,39 @@
|
| Source<SpellCheckHost>(this), NotificationService::NoDetails());
|
| }
|
|
|
| +void SpellCheckHost::InitializeDictionaryLocation() {
|
| + DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE));
|
| +
|
| +#if defined(OS_WIN)
|
| + // Check if the dictionary exists in the fallback location. If so, use it
|
| + // rather than downloading anew.
|
| + FilePath fallback = GetFallbackFilePath(bdict_file_path_);
|
| + if (!file_util::PathExists(bdict_file_path_) &&
|
| + file_util::PathExists(fallback)) {
|
| + bdict_file_path_ = fallback;
|
| + }
|
| +#endif
|
| +
|
| + Initialize();
|
| +}
|
| +
|
| void SpellCheckHost::Initialize() {
|
| DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE));
|
|
|
| if (!observer_)
|
| return;
|
|
|
| - // We set |auto_close| to false because we don't want IPC to close the fd.
|
| - // We will close it manually in the destructor.
|
| - fd_ = base::FileDescriptor(open(bdict_file_.value().c_str(), O_RDONLY),
|
| - false);
|
| + file_ = base::CreatePlatformFile(bdict_file_path_,
|
| + base::PLATFORM_FILE_READ | base::PLATFORM_FILE_OPEN,
|
| + NULL);
|
|
|
| // File didn't exist. Download it.
|
| - if (fd_.fd == -1 && !tried_to_download_) {
|
| + if (file_ == base::kInvalidPlatformFileValue && !tried_to_download_) {
|
| DownloadDictionary();
|
| return;
|
| }
|
|
|
| - if (fd_.fd != -1) {
|
| + if (file_ != base::kInvalidPlatformFileValue) {
|
| // Load custom dictionary.
|
| std::string contents;
|
| file_util::ReadFileToString(custom_dictionary_file_, &contents);
|
| @@ -218,7 +242,7 @@
|
| static const char kDownloadServerUrl[] =
|
| "http://cache.pack.google.com/edgedl/chrome/dict/";
|
| GURL url = GURL(std::string(kDownloadServerUrl) + WideToUTF8(
|
| - l10n_util::ToLower(bdict_file_.BaseName().ToWStringHack())));
|
| + l10n_util::ToLower(bdict_file_path_.BaseName().ToWStringHack())));
|
| fetcher_.reset(new URLFetcher(url, URLFetcher::GET, this));
|
| fetcher_->set_request_context(request_context_getter_.get());
|
| tried_to_download_ = true;
|
| @@ -263,15 +287,27 @@
|
| }
|
|
|
| size_t bytes_written =
|
| - file_util::WriteFile(bdict_file_, data.data(), data.length());
|
| + file_util::WriteFile(bdict_file_path_, data.data(), data.length());
|
| if (bytes_written != data.length()) {
|
| - LOG(ERROR) << "Failure to save dictionary.";
|
| - // To avoid trying to load a partially saved dictionary, shortcut the
|
| - // Initialize() call.
|
| - ChromeThread::PostTask(ChromeThread::UI, FROM_HERE,
|
| - NewRunnableMethod(this,
|
| - &SpellCheckHost::InformObserverOfInitialization));
|
| - return;
|
| + bool success = false;
|
| +#if defined(OS_WIN)
|
| + bdict_file_path_ = GetFallbackFilePath(bdict_file_path_);
|
| + bytes_written =
|
| + file_util::WriteFile(GetFallbackFilePath(bdict_file_path_),
|
| + data.data(), data.length());
|
| + if (bytes_written == data.length())
|
| + success = true;
|
| +#endif
|
| +
|
| + if (!success) {
|
| + LOG(ERROR) << "Failure to save dictionary.";
|
| + // To avoid trying to load a partially saved dictionary, shortcut the
|
| + // Initialize() call.
|
| + ChromeThread::PostTask(ChromeThread::UI, FROM_HERE,
|
| + NewRunnableMethod(this,
|
| + &SpellCheckHost::InformObserverOfInitialization));
|
| + return;
|
| + }
|
| }
|
|
|
| Initialize();
|
|
|