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

Side by Side Diff: chrome/browser/spellcheck_host.cc

Issue 397017: reland 31875. Revert was:... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 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
« no previous file with comments | « chrome/browser/spellcheck_host.h ('k') | chrome/chrome.gyp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 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/spellcheck_host.h" 5 #include "chrome/browser/spellcheck_host.h"
6 6
7 #include <fcntl.h> 7 #include <fcntl.h>
8 8
9 #include "app/l10n_util.h" 9 #include "app/l10n_util.h"
10 #include "base/file_util.h" 10 #include "base/file_util.h"
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
114 if (language == special_version_string[i].language) { 114 if (language == special_version_string[i].language) {
115 versioned_bdict_file_name = 115 versioned_bdict_file_name =
116 language + special_version_string[i].version + ".bdic"; 116 language + special_version_string[i].version + ".bdic";
117 break; 117 break;
118 } 118 }
119 } 119 }
120 120
121 return dict_dir.AppendASCII(versioned_bdict_file_name); 121 return dict_dir.AppendASCII(versioned_bdict_file_name);
122 } 122 }
123 123
124 FilePath GetFirstChoiceFilePath(const std::string& language) {
125 FilePath dict_dir;
126 PathService::Get(chrome::DIR_APP_DICTIONARIES, &dict_dir);
127 return GetVersionedFileName(language, dict_dir);
128 }
129
130 FilePath GetFallbackFilePath(const FilePath& first_choice) {
131 FilePath dict_dir;
132 PathService::Get(chrome::DIR_USER_DATA, &dict_dir);
133 return dict_dir.Append(first_choice.BaseName());
134 }
135
124 } // namespace 136 } // namespace
125 137
126 // Constructed on UI thread. 138 // Constructed on UI thread.
127 SpellCheckHost::SpellCheckHost(Observer* observer, 139 SpellCheckHost::SpellCheckHost(Observer* observer,
128 const std::string& language, 140 const std::string& language,
129 URLRequestContextGetter* request_context_getter) 141 URLRequestContextGetter* request_context_getter)
130 : observer_(observer), 142 : observer_(observer),
131 language_(language), 143 language_(language),
144 file_(base::kInvalidPlatformFileValue),
132 tried_to_download_(false), 145 tried_to_download_(false),
133 request_context_getter_(request_context_getter) { 146 request_context_getter_(request_context_getter) {
134 DCHECK(observer_); 147 DCHECK(observer_);
135 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); 148 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
136 149
137 // TODO(estade): for Windows, we need to fall back to DIR_USER_DATA if
138 // DIR_APP_DICTIONARIES is not writeable.
139 FilePath dict_dir;
140 PathService::Get(chrome::DIR_APP_DICTIONARIES, &dict_dir);
141 bdict_file_ = GetVersionedFileName(language, dict_dir);
142
143 FilePath personal_file_directory; 150 FilePath personal_file_directory;
144 PathService::Get(chrome::DIR_USER_DATA, &personal_file_directory); 151 PathService::Get(chrome::DIR_USER_DATA, &personal_file_directory);
145 custom_dictionary_file_ = 152 custom_dictionary_file_ =
146 personal_file_directory.Append(chrome::kCustomDictionaryFileName); 153 personal_file_directory.Append(chrome::kCustomDictionaryFileName);
154
155 bdict_file_path_ = GetFirstChoiceFilePath(language);
147 } 156 }
148 157
149 SpellCheckHost::~SpellCheckHost() { 158 SpellCheckHost::~SpellCheckHost() {
150 if (fd_.fd != -1) 159 if (file_ != base::kInvalidPlatformFileValue)
151 close(fd_.fd); 160 base::ClosePlatformFile(file_);
152 } 161 }
153 162
154 void SpellCheckHost::Initialize() { 163 void SpellCheckHost::Initialize() {
155 ChromeThread::PostTask(ChromeThread::FILE, FROM_HERE, 164 ChromeThread::PostTask(ChromeThread::FILE, FROM_HERE,
156 NewRunnableMethod(this, &SpellCheckHost::InitializeInternal)); 165 NewRunnableMethod(this, &SpellCheckHost::InitializeDictionaryLocation));
157 } 166 }
158 167
159 void SpellCheckHost::UnsetObserver() { 168 void SpellCheckHost::UnsetObserver() {
160 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); 169 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
161 170
162 observer_ = NULL; 171 observer_ = NULL;
163 } 172 }
164 173
165 void SpellCheckHost::AddWord(const std::string& word) { 174 void SpellCheckHost::AddWord(const std::string& word) {
166 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); 175 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
167 176
168 custom_words_.push_back(word); 177 custom_words_.push_back(word);
169 ChromeThread::PostTask(ChromeThread::FILE, FROM_HERE, 178 ChromeThread::PostTask(ChromeThread::FILE, FROM_HERE,
170 NewRunnableMethod(this, 179 NewRunnableMethod(this,
171 &SpellCheckHost::WriteWordToCustomDictionary, word)); 180 &SpellCheckHost::WriteWordToCustomDictionary, word));
172 NotificationService::current()->Notify( 181 NotificationService::current()->Notify(
173 NotificationType::SPELLCHECK_WORD_ADDED, 182 NotificationType::SPELLCHECK_WORD_ADDED,
174 Source<SpellCheckHost>(this), NotificationService::NoDetails()); 183 Source<SpellCheckHost>(this), NotificationService::NoDetails());
175 } 184 }
176 185
186 void SpellCheckHost::InitializeDictionaryLocation() {
187 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE));
188
189 #if defined(OS_WIN)
190 // Check if the dictionary exists in the fallback location. If so, use it
191 // rather than downloading anew.
192 FilePath fallback = GetFallbackFilePath(bdict_file_path_);
193 if (!file_util::PathExists(bdict_file_path_) &&
194 file_util::PathExists(fallback)) {
195 bdict_file_path_ = fallback;
196 }
197 #endif
198
199 InitializeInternal();
200 }
201
177 void SpellCheckHost::InitializeInternal() { 202 void SpellCheckHost::InitializeInternal() {
178 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE)); 203 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE));
179 204
180 if (!observer_) 205 if (!observer_)
181 return; 206 return;
182 207
183 // We set |auto_close| to false because we don't want IPC to close the fd. 208 file_ = base::CreatePlatformFile(bdict_file_path_,
184 // We will close it manually in the destructor. 209 base::PLATFORM_FILE_READ | base::PLATFORM_FILE_OPEN,
185 fd_ = base::FileDescriptor(open(bdict_file_.value().c_str(), O_RDONLY), 210 NULL);
186 false);
187 211
188 // File didn't exist. Download it. 212 // File didn't exist. Download it.
189 if (fd_.fd == -1 && !tried_to_download_) { 213 if (file_ == base::kInvalidPlatformFileValue && !tried_to_download_) {
190 DownloadDictionary(); 214 DownloadDictionary();
191 return; 215 return;
192 } 216 }
193 217
194 if (fd_.fd != -1) { 218 if (file_ != base::kInvalidPlatformFileValue) {
195 // Load custom dictionary. 219 // Load custom dictionary.
196 std::string contents; 220 std::string contents;
197 file_util::ReadFileToString(custom_dictionary_file_, &contents); 221 file_util::ReadFileToString(custom_dictionary_file_, &contents);
198 std::vector<std::string> list_of_words; 222 std::vector<std::string> list_of_words;
199 SplitString(contents, '\n', &list_of_words); 223 SplitString(contents, '\n', &list_of_words);
200 for (size_t i = 0; i < list_of_words.size(); ++i) 224 for (size_t i = 0; i < list_of_words.size(); ++i)
201 custom_words_.push_back(list_of_words[i]); 225 custom_words_.push_back(list_of_words[i]);
202 } 226 }
203 227
204 ChromeThread::PostTask(ChromeThread::UI, FROM_HERE, 228 ChromeThread::PostTask(ChromeThread::UI, FROM_HERE,
205 NewRunnableMethod(this, 229 NewRunnableMethod(this,
206 &SpellCheckHost::InformObserverOfInitialization)); 230 &SpellCheckHost::InformObserverOfInitialization));
207 } 231 }
208 232
209 void SpellCheckHost::InformObserverOfInitialization() { 233 void SpellCheckHost::InformObserverOfInitialization() {
210 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); 234 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
211 235
212 if (observer_) 236 if (observer_)
213 observer_->SpellCheckHostInitialized(); 237 observer_->SpellCheckHostInitialized();
214 } 238 }
215 239
216 void SpellCheckHost::DownloadDictionary() { 240 void SpellCheckHost::DownloadDictionary() {
217 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE)); 241 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE));
218 242
219 // Determine URL of file to download. 243 // Determine URL of file to download.
220 static const char kDownloadServerUrl[] = 244 static const char kDownloadServerUrl[] =
221 "http://cache.pack.google.com/edgedl/chrome/dict/"; 245 "http://cache.pack.google.com/edgedl/chrome/dict/";
222 GURL url = GURL(std::string(kDownloadServerUrl) + WideToUTF8( 246 GURL url = GURL(std::string(kDownloadServerUrl) + WideToUTF8(
223 l10n_util::ToLower(bdict_file_.BaseName().ToWStringHack()))); 247 l10n_util::ToLower(bdict_file_path_.BaseName().ToWStringHack())));
224 fetcher_.reset(new URLFetcher(url, URLFetcher::GET, this)); 248 fetcher_.reset(new URLFetcher(url, URLFetcher::GET, this));
225 fetcher_->set_request_context(request_context_getter_.get()); 249 fetcher_->set_request_context(request_context_getter_.get());
226 tried_to_download_ = true; 250 tried_to_download_ = true;
227 fetcher_->Start(); 251 fetcher_->Start();
228 } 252 }
229 253
230 void SpellCheckHost::WriteWordToCustomDictionary(const std::string& word) { 254 void SpellCheckHost::WriteWordToCustomDictionary(const std::string& word) {
231 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE)); 255 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE));
232 256
233 // Stored in UTF-8. 257 // Stored in UTF-8.
(...skipping 24 matching lines...) Expand all
258 // There's the small chance that we might see a 200 status code for a body 282 // There's the small chance that we might see a 200 status code for a body
259 // that represents some form of failure. 283 // that represents some form of failure.
260 if (data.size() < 4 || data[0] != 'B' || data[1] != 'D' || data[2] != 'i' || 284 if (data.size() < 4 || data[0] != 'B' || data[1] != 'D' || data[2] != 'i' ||
261 data[3] != 'c') { 285 data[3] != 'c') {
262 LOG(ERROR) << "Failure to download dictionary."; 286 LOG(ERROR) << "Failure to download dictionary.";
263 Initialize(); 287 Initialize();
264 return; 288 return;
265 } 289 }
266 290
267 size_t bytes_written = 291 size_t bytes_written =
268 file_util::WriteFile(bdict_file_, data.data(), data.length()); 292 file_util::WriteFile(bdict_file_path_, data.data(), data.length());
269 if (bytes_written != data.length()) { 293 if (bytes_written != data.length()) {
270 LOG(ERROR) << "Failure to save dictionary."; 294 bool success = false;
271 // To avoid trying to load a partially saved dictionary, shortcut the 295 #if defined(OS_WIN)
272 // Initialize() call. 296 bdict_file_path_ = GetFallbackFilePath(bdict_file_path_);
273 ChromeThread::PostTask(ChromeThread::UI, FROM_HERE, 297 bytes_written =
274 NewRunnableMethod(this, 298 file_util::WriteFile(GetFallbackFilePath(bdict_file_path_),
275 &SpellCheckHost::InformObserverOfInitialization)); 299 data.data(), data.length());
276 return; 300 if (bytes_written == data.length())
301 success = true;
302 #endif
303
304 if (!success) {
305 LOG(ERROR) << "Failure to save dictionary.";
306 // To avoid trying to load a partially saved dictionary, shortcut the
307 // Initialize() call.
308 ChromeThread::PostTask(ChromeThread::UI, FROM_HERE,
309 NewRunnableMethod(this,
310 &SpellCheckHost::InformObserverOfInitialization));
311 return;
312 }
277 } 313 }
278 314
279 Initialize(); 315 Initialize();
280 } 316 }
OLDNEW
« no previous file with comments | « chrome/browser/spellcheck_host.h ('k') | chrome/chrome.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698