OLD | NEW |
---|---|
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/profiles/profile_impl.h" | 5 #include "chrome/browser/profiles/profile_impl.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
9 #include "base/compiler_specific.h" | 9 #include "base/compiler_specific.h" |
10 #include "base/environment.h" | 10 #include "base/environment.h" |
11 #include "base/file_path.h" | 11 #include "base/file_path.h" |
12 #include "base/file_util.h" | 12 #include "base/file_util.h" |
13 #include "base/memory/scoped_ptr.h" | 13 #include "base/memory/scoped_ptr.h" |
14 #include "base/path_service.h" | 14 #include "base/path_service.h" |
15 #include "base/prefs/json_pref_store.h" | |
15 #include "base/string_number_conversions.h" | 16 #include "base/string_number_conversions.h" |
16 #include "base/string_tokenizer.h" | 17 #include "base/string_tokenizer.h" |
17 #include "base/string_util.h" | 18 #include "base/string_util.h" |
18 #include "base/stringprintf.h" | 19 #include "base/stringprintf.h" |
20 #include "base/synchronization/waitable_event.h" | |
21 #include "base/threading/sequenced_worker_pool.h" | |
19 #include "base/utf_string_conversions.h" | 22 #include "base/utf_string_conversions.h" |
20 #include "base/version.h" | 23 #include "base/version.h" |
21 #include "chrome/browser/autocomplete/autocomplete_classifier.h" | 24 #include "chrome/browser/autocomplete/autocomplete_classifier.h" |
22 #include "chrome/browser/background/background_contents_service_factory.h" | 25 #include "chrome/browser/background/background_contents_service_factory.h" |
23 #include "chrome/browser/background/background_mode_manager.h" | 26 #include "chrome/browser/background/background_mode_manager.h" |
24 #include "chrome/browser/browser_process.h" | 27 #include "chrome/browser/browser_process.h" |
25 #include "chrome/browser/chrome_plugin_service_filter.h" | 28 #include "chrome/browser/chrome_plugin_service_filter.h" |
26 #include "chrome/browser/content_settings/cookie_settings.h" | 29 #include "chrome/browser/content_settings/cookie_settings.h" |
27 #include "chrome/browser/content_settings/host_content_settings_map.h" | 30 #include "chrome/browser/content_settings/host_content_settings_map.h" |
28 #include "chrome/browser/custom_handlers/protocol_handler_registry.h" | 31 #include "chrome/browser/custom_handlers/protocol_handler_registry.h" |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
148 "information and MUST not be extracted, overwritten or modified except " | 151 "information and MUST not be extracted, overwritten or modified except " |
149 "through %s defined APIs."; | 152 "through %s defined APIs."; |
150 | 153 |
151 // Value written to prefs for EXIT_CRASHED and EXIT_SESSION_ENDED. | 154 // Value written to prefs for EXIT_CRASHED and EXIT_SESSION_ENDED. |
152 const char* const kPrefExitTypeCrashed = "Crashed"; | 155 const char* const kPrefExitTypeCrashed = "Crashed"; |
153 const char* const kPrefExitTypeSessionEnded = "SessionEnded"; | 156 const char* const kPrefExitTypeSessionEnded = "SessionEnded"; |
154 | 157 |
155 // Helper method needed because PostTask cannot currently take a Callback | 158 // Helper method needed because PostTask cannot currently take a Callback |
156 // function with non-void return type. | 159 // function with non-void return type. |
157 // TODO(jhawkins): Remove once IgnoreResult is fixed. | 160 // TODO(jhawkins): Remove once IgnoreResult is fixed. |
158 void CreateDirectoryNoResult(const FilePath& path) { | 161 void CreateDirectoryNoResult(const FilePath& path, |
Mattias Nissler (ping if slow)
2012/10/24 17:07:49
nit: Rename to CreateDirectoryAndSignal or somesuc
zel
2012/10/24 17:23:14
Done.
| |
162 base::WaitableEvent* done_creating) { | |
159 file_util::CreateDirectory(path); | 163 file_util::CreateDirectory(path); |
164 done_creating->Signal(); | |
165 } | |
166 | |
167 // Task that blocks the FILE thread until CreateDirectoryNoResult() finishes on | |
168 // blocking I/O pool. | |
169 void BlockFileThreadOnDirectoryCreate(base::WaitableEvent* done_creating) { | |
170 done_creating->Wait(); | |
171 } | |
172 | |
173 // Initiates creation of profile directory on |sequenced_task_runner| and | |
174 // ensures that FILE thread is blocked until that operation finishes. | |
175 void CreateProfileDirectory(base::SequencedTaskRunner* sequenced_task_runner, | |
176 const FilePath& path) { | |
177 base::WaitableEvent* done_creating = new base::WaitableEvent(false, false); | |
178 sequenced_task_runner->PostTask(FROM_HERE, | |
179 base::Bind(&CreateDirectoryNoResult, | |
180 path, | |
181 done_creating)); | |
182 // Block the FILE thread until directory is created on I/O pool to make sure | |
183 // that we don't attempt any operation until that part completes. | |
184 BrowserThread::PostTask( | |
185 BrowserThread::FILE, FROM_HERE, | |
Mattias Nissler (ping if slow)
2012/10/24 17:07:49
nit: indentation
zel
2012/10/24 17:23:14
Done.
| |
186 base::Bind(&BlockFileThreadOnDirectoryCreate, | |
187 base::Owned(done_creating))); | |
160 } | 188 } |
161 | 189 |
162 FilePath GetCachePath(const FilePath& base) { | 190 FilePath GetCachePath(const FilePath& base) { |
163 return base.Append(chrome::kCacheDirname); | 191 return base.Append(chrome::kCacheDirname); |
164 } | 192 } |
165 | 193 |
166 FilePath GetMediaCachePath(const FilePath& base) { | 194 FilePath GetMediaCachePath(const FilePath& base) { |
167 return base.Append(chrome::kMediaCacheDirname); | 195 return base.Append(chrome::kMediaCacheDirname); |
168 } | 196 } |
169 | 197 |
(...skipping 28 matching lines...) Expand all Loading... | |
198 return kPrefExitTypeSessionEnded; | 226 return kPrefExitTypeSessionEnded; |
199 case Profile::EXIT_CRASHED: | 227 case Profile::EXIT_CRASHED: |
200 return kPrefExitTypeCrashed; | 228 return kPrefExitTypeCrashed; |
201 } | 229 } |
202 NOTREACHED(); | 230 NOTREACHED(); |
203 return std::string(); | 231 return std::string(); |
204 } | 232 } |
205 | 233 |
206 } // namespace | 234 } // namespace |
207 | 235 |
236 | |
Mattias Nissler (ping if slow)
2012/10/24 17:07:49
remove extra newline
zel
2012/10/24 17:23:14
Done.
| |
208 // static | 237 // static |
209 Profile* Profile::CreateProfile(const FilePath& path, | 238 Profile* Profile::CreateProfile(const FilePath& path, |
210 Delegate* delegate, | 239 Delegate* delegate, |
211 CreateMode create_mode) { | 240 CreateMode create_mode) { |
241 // Get sequenced task runner for making sure that file operations of | |
242 // this profile (defined by |path|) are executed in expected order | |
243 // (what was previously assured by the FILE thread). | |
244 scoped_refptr<base::SequencedTaskRunner> sequenced_task_runner = | |
245 JsonPrefStore::GetTaskRunnerForFile(path, | |
246 BrowserThread::GetBlockingPool()); | |
212 if (create_mode == CREATE_MODE_ASYNCHRONOUS) { | 247 if (create_mode == CREATE_MODE_ASYNCHRONOUS) { |
213 DCHECK(delegate); | 248 DCHECK(delegate); |
214 // This is safe while all file operations are done on the FILE thread. | 249 CreateProfileDirectory(sequenced_task_runner, path); |
215 BrowserThread::PostTask( | |
216 BrowserThread::FILE, FROM_HERE, | |
217 base::Bind(&CreateDirectoryNoResult, path)); | |
218 } else if (create_mode == CREATE_MODE_SYNCHRONOUS) { | 250 } else if (create_mode == CREATE_MODE_SYNCHRONOUS) { |
219 if (!file_util::PathExists(path)) { | 251 if (!file_util::PathExists(path)) { |
220 // TODO(tc): http://b/1094718 Bad things happen if we can't write to the | 252 // TODO(tc): http://b/1094718 Bad things happen if we can't write to the |
221 // profile directory. We should eventually be able to run in this | 253 // profile directory. We should eventually be able to run in this |
222 // situation. | 254 // situation. |
223 if (!file_util::CreateDirectory(path)) | 255 if (!file_util::CreateDirectory(path)) |
224 return NULL; | 256 return NULL; |
225 } | 257 } |
226 } else { | 258 } else { |
227 NOTREACHED(); | 259 NOTREACHED(); |
228 } | 260 } |
229 | 261 |
230 return new ProfileImpl(path, delegate, create_mode); | 262 return new ProfileImpl(path, delegate, create_mode, sequenced_task_runner); |
231 } | 263 } |
232 | 264 |
233 // static | 265 // static |
234 int ProfileImpl::create_readme_delay_ms = 60000; | 266 int ProfileImpl::create_readme_delay_ms = 60000; |
235 | 267 |
236 // static | 268 // static |
237 const char* const ProfileImpl::kPrefExitTypeNormal = "Normal"; | 269 const char* const ProfileImpl::kPrefExitTypeNormal = "Normal"; |
238 | 270 |
239 // static | 271 // static |
240 void ProfileImpl::RegisterUserPrefs(PrefService* prefs) { | 272 void ProfileImpl::RegisterUserPrefs(PrefService* prefs) { |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
273 prefs->RegisterIntegerPref(prefs::kMediaCacheSize, | 305 prefs->RegisterIntegerPref(prefs::kMediaCacheSize, |
274 0, | 306 0, |
275 PrefService::UNSYNCABLE_PREF); | 307 PrefService::UNSYNCABLE_PREF); |
276 | 308 |
277 // Deprecated. Kept around for migration. | 309 // Deprecated. Kept around for migration. |
278 prefs->RegisterBooleanPref(prefs::kClearSiteDataOnExit, | 310 prefs->RegisterBooleanPref(prefs::kClearSiteDataOnExit, |
279 false, | 311 false, |
280 PrefService::SYNCABLE_PREF); | 312 PrefService::SYNCABLE_PREF); |
281 } | 313 } |
282 | 314 |
283 ProfileImpl::ProfileImpl(const FilePath& path, | 315 ProfileImpl::ProfileImpl( |
284 Delegate* delegate, | 316 const FilePath& path, |
285 CreateMode create_mode) | 317 Delegate* delegate, |
318 CreateMode create_mode, | |
319 base::SequencedTaskRunner* sequenced_task_runner) | |
286 : path_(path), | 320 : path_(path), |
287 ALLOW_THIS_IN_INITIALIZER_LIST(visited_link_event_listener_( | 321 ALLOW_THIS_IN_INITIALIZER_LIST(visited_link_event_listener_( |
288 new VisitedLinkEventListener(this))), | 322 new VisitedLinkEventListener(this))), |
289 ALLOW_THIS_IN_INITIALIZER_LIST(io_data_(this)), | 323 ALLOW_THIS_IN_INITIALIZER_LIST(io_data_(this)), |
290 host_content_settings_map_(NULL), | 324 host_content_settings_map_(NULL), |
291 last_session_exit_type_(EXIT_NORMAL), | 325 last_session_exit_type_(EXIT_NORMAL), |
292 start_time_(Time::Now()), | 326 start_time_(Time::Now()), |
293 delegate_(delegate), | 327 delegate_(delegate), |
294 predictor_(NULL) { | 328 predictor_(NULL) { |
295 DCHECK(!path.empty()) << "Using an empty path will attempt to write " << | 329 DCHECK(!path.empty()) << "Using an empty path will attempt to write " << |
(...skipping 26 matching lines...) Expand all Loading... | |
322 policy::ManagedModePolicyProvider::Create(this)); | 356 policy::ManagedModePolicyProvider::Create(this)); |
323 managed_mode_policy_provider_->Init(); | 357 managed_mode_policy_provider_->Init(); |
324 policy_service_ = connector->CreatePolicyService(this); | 358 policy_service_ = connector->CreatePolicyService(this); |
325 #else | 359 #else |
326 policy_service_.reset(new policy::PolicyServiceStub()); | 360 policy_service_.reset(new policy::PolicyServiceStub()); |
327 #endif | 361 #endif |
328 | 362 |
329 if (create_mode == CREATE_MODE_ASYNCHRONOUS) { | 363 if (create_mode == CREATE_MODE_ASYNCHRONOUS) { |
330 prefs_.reset(PrefService::CreatePrefService( | 364 prefs_.reset(PrefService::CreatePrefService( |
331 GetPrefFilePath(), | 365 GetPrefFilePath(), |
366 sequenced_task_runner, | |
332 policy_service_.get(), | 367 policy_service_.get(), |
333 new ExtensionPrefStore( | 368 new ExtensionPrefStore( |
334 ExtensionPrefValueMapFactory::GetForProfile(this), false), | 369 ExtensionPrefValueMapFactory::GetForProfile(this), false), |
335 true)); | 370 true)); |
336 // Wait for the notification that prefs has been loaded (successfully or | 371 // Wait for the notification that prefs has been loaded (successfully or |
337 // not). | 372 // not). |
338 registrar_.Add(this, chrome::NOTIFICATION_PREF_INITIALIZATION_COMPLETED, | 373 registrar_.Add(this, chrome::NOTIFICATION_PREF_INITIALIZATION_COMPLETED, |
339 content::Source<PrefService>(prefs_.get())); | 374 content::Source<PrefService>(prefs_.get())); |
340 } else if (create_mode == CREATE_MODE_SYNCHRONOUS) { | 375 } else if (create_mode == CREATE_MODE_SYNCHRONOUS) { |
341 // Load prefs synchronously. | 376 // Load prefs synchronously. |
342 prefs_.reset(PrefService::CreatePrefService( | 377 prefs_.reset(PrefService::CreatePrefService( |
343 GetPrefFilePath(), | 378 GetPrefFilePath(), |
379 sequenced_task_runner, | |
344 policy_service_.get(), | 380 policy_service_.get(), |
345 new ExtensionPrefStore( | 381 new ExtensionPrefStore( |
346 ExtensionPrefValueMapFactory::GetForProfile(this), false), | 382 ExtensionPrefValueMapFactory::GetForProfile(this), false), |
347 false)); | 383 false)); |
348 OnPrefsLoaded(true); | 384 OnPrefsLoaded(true); |
349 } else { | 385 } else { |
350 NOTREACHED(); | 386 NOTREACHED(); |
351 } | 387 } |
352 } | 388 } |
353 | 389 |
354 void ProfileImpl::DoFinalInit(bool is_new_profile) { | 390 void ProfileImpl::DoFinalInit(bool is_new_profile) { |
355 PrefService* prefs = GetPrefs(); | 391 PrefService* prefs = GetPrefs(); |
356 pref_change_registrar_.Init(prefs); | 392 pref_change_registrar_.Init(prefs); |
357 pref_change_registrar_.Add(prefs::kGoogleServicesUsername, this); | 393 pref_change_registrar_.Add(prefs::kGoogleServicesUsername, this); |
358 pref_change_registrar_.Add(prefs::kDefaultZoomLevel, this); | 394 pref_change_registrar_.Add(prefs::kDefaultZoomLevel, this); |
359 pref_change_registrar_.Add(prefs::kProfileAvatarIndex, this); | 395 pref_change_registrar_.Add(prefs::kProfileAvatarIndex, this); |
360 pref_change_registrar_.Add(prefs::kProfileName, this); | 396 pref_change_registrar_.Add(prefs::kProfileName, this); |
361 | 397 |
362 // It would be nice to use PathService for fetching this directory, but | 398 // It would be nice to use PathService for fetching this directory, but |
363 // the cache directory depends on the profile directory, which isn't available | 399 // the cache directory depends on the profile directory, which isn't available |
364 // to PathService. | 400 // to PathService. |
365 chrome::GetUserCacheDirectory(path_, &base_cache_path_); | 401 chrome::GetUserCacheDirectory(path_, &base_cache_path_); |
366 // Always create the cache directory asynchronously. | 402 // Always create the cache directory asynchronously. |
367 BrowserThread::PostTask( | 403 scoped_refptr<base::SequencedTaskRunner> sequenced_task_runner = |
368 BrowserThread::FILE, FROM_HERE, | 404 JsonPrefStore::GetTaskRunnerForFile(base_cache_path_, |
369 base::Bind(&CreateDirectoryNoResult, base_cache_path_)); | 405 BrowserThread::GetBlockingPool()); |
406 CreateProfileDirectory(sequenced_task_runner, base_cache_path_); | |
370 | 407 |
371 // Now that the profile is hooked up to receive pref change notifications to | 408 // Now that the profile is hooked up to receive pref change notifications to |
372 // kGoogleServicesUsername, initialize components that depend on it to reflect | 409 // kGoogleServicesUsername, initialize components that depend on it to reflect |
373 // the current value. | 410 // the current value. |
374 UpdateProfileUserNameCache(); | 411 UpdateProfileUserNameCache(); |
375 GetGAIAInfoUpdateService(); | 412 GetGAIAInfoUpdateService(); |
376 | 413 |
377 #if !defined(OS_CHROMEOS) | 414 #if !defined(OS_CHROMEOS) |
378 // Listen for bookmark model load, to bootstrap the sync service. | 415 // Listen for bookmark model load, to bootstrap the sync service. |
379 // On CrOS sync service will be initialized after sign in. | 416 // On CrOS sync service will be initialized after sign in. |
(...skipping 786 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1166 if (!path.empty()) | 1203 if (!path.empty()) |
1167 *cache_path = path; | 1204 *cache_path = path; |
1168 *max_size = is_media_context ? prefs_->GetInteger(prefs::kMediaCacheSize) : | 1205 *max_size = is_media_context ? prefs_->GetInteger(prefs::kMediaCacheSize) : |
1169 prefs_->GetInteger(prefs::kDiskCacheSize); | 1206 prefs_->GetInteger(prefs::kDiskCacheSize); |
1170 } | 1207 } |
1171 | 1208 |
1172 base::Callback<ChromeURLDataManagerBackend*(void)> | 1209 base::Callback<ChromeURLDataManagerBackend*(void)> |
1173 ProfileImpl::GetChromeURLDataManagerBackendGetter() const { | 1210 ProfileImpl::GetChromeURLDataManagerBackendGetter() const { |
1174 return io_data_.GetChromeURLDataManagerBackendGetter(); | 1211 return io_data_.GetChromeURLDataManagerBackendGetter(); |
1175 } | 1212 } |
OLD | NEW |