Index: ios/chrome/browser/browser_state/chrome_browser_state_impl.cc |
diff --git a/ios/chrome/browser/browser_state/chrome_browser_state_impl.cc b/ios/chrome/browser/browser_state/chrome_browser_state_impl.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..abdd9555660909a13617670e664ca7919d4fd456 |
--- /dev/null |
+++ b/ios/chrome/browser/browser_state/chrome_browser_state_impl.cc |
@@ -0,0 +1,260 @@ |
+// Copyright 2013 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "ios/chrome/browser/browser_state/chrome_browser_state_impl.h" |
+ |
+#include <utility> |
+ |
+#include "base/files/file_path.h" |
+#include "base/files/file_util.h" |
+#include "base/logging.h" |
+#include "base/synchronization/waitable_event.h" |
+#include "components/bookmarks/browser/bookmark_model.h" |
+#include "components/keyed_service/ios/browser_state_dependency_manager.h" |
+#include "components/pref_registry/pref_registry_syncable.h" |
+#include "components/prefs/json_pref_store.h" |
+#include "components/prefs/pref_service.h" |
+#include "components/proxy_config/pref_proxy_config_tracker.h" |
+#include "components/syncable_prefs/pref_service_syncable.h" |
+#include "components/user_prefs/user_prefs.h" |
+#include "ios/chrome/browser/application_context.h" |
+#include "ios/chrome/browser/bookmarks/bookmark_model_factory.h" |
+#include "ios/chrome/browser/browser_state/bookmark_model_loaded_observer.h" |
+#include "ios/chrome/browser/browser_state/off_the_record_chrome_browser_state_impl.h" |
+#include "ios/chrome/browser/chrome_constants.h" |
+#include "ios/chrome/browser/chrome_paths_internal.h" |
+#include "ios/chrome/browser/file_metadata_util.h" |
+#include "ios/chrome/browser/net/ios_chrome_url_request_context_getter.h" |
+#include "ios/chrome/browser/net/proxy_service_factory.h" |
+#include "ios/chrome/browser/pref_names.h" |
+#include "ios/chrome/browser/prefs/browser_prefs.h" |
+#include "ios/chrome/browser/prefs/ios_chrome_pref_service_factory.h" |
+#include "ios/web/public/web_thread.h" |
+ |
+namespace { |
+ |
+// Returns a bool indicating whether the necessary directories were able to be |
+// created (or already existed). |
+bool EnsureBrowserStateDirectoriesCreated(const base::FilePath& path, |
+ const base::FilePath& otr_path) { |
+ if (!base::PathExists(path) && !base::CreateDirectory(path)) |
+ return false; |
+ // Create the directory for the OTR stash state now, even though it won't |
+ // necessarily be needed: the OTR browser state itself is created |
+ // synchronously on an as-needed basis on the UI thread, so creation of its |
+ // stash state directory cannot easily be done at that point. |
+ if (base::PathExists(otr_path)) |
+ return true; |
+ if (!base::CreateDirectory(otr_path)) |
+ return false; |
+ SetSkipSystemBackupAttributeToItem(otr_path, true); |
+ return true; |
+} |
+ |
+// Task that creates the directory and signal the FILE thread to resume |
+// execution. |
+void CreateDirectoryAndSignal(const base::FilePath& path, |
+ base::WaitableEvent* done_creating) { |
+ bool success = base::CreateDirectory(path); |
+ DCHECK(success); |
+ done_creating->Signal(); |
+} |
+ |
+// Task that blocks the FILE thread until CreateDirectoryAndSignal() finishes on |
+// blocking I/O pool. |
+void BlockFileThreadOnDirectoryCreate(base::WaitableEvent* done_creating) { |
+ done_creating->Wait(); |
+} |
+ |
+// Initiates creation of browser state directory on |sequenced_task_runner| and |
+// ensures that FILE thread is blocked until that operation finishes. |
+void CreateBrowserStateDirectory( |
+ base::SequencedTaskRunner* sequenced_task_runner, |
+ const base::FilePath& path) { |
+ base::WaitableEvent* done_creating = new base::WaitableEvent(false, false); |
+ sequenced_task_runner->PostTask( |
+ FROM_HERE, base::Bind(&CreateDirectoryAndSignal, path, done_creating)); |
+ // Block the FILE thread until directory is created on I/O pool to make sure |
+ // that we don't attempt any operation until that part completes. |
+ web::WebThread::PostTask(web::WebThread::FILE, FROM_HERE, |
+ base::Bind(&BlockFileThreadOnDirectoryCreate, |
+ base::Owned(done_creating))); |
+} |
+ |
+base::FilePath GetCachePath(const base::FilePath& base) { |
+ return base.Append(kIOSChromeCacheDirname); |
+} |
+ |
+} // namespace |
+ |
+ChromeBrowserStateImpl::ChromeBrowserStateImpl(const base::FilePath& path) |
+ : state_path_(path), |
+ pref_registry_(new user_prefs::PrefRegistrySyncable), |
+ io_data_(new ChromeBrowserStateImplIOData::Handle(this)) { |
+ otr_state_path_ = state_path_.Append(FILE_PATH_LITERAL("OTR")); |
+ |
+ bool directories_created = |
+ EnsureBrowserStateDirectoriesCreated(state_path_, otr_state_path_); |
+ DCHECK(directories_created); |
+ |
+ RegisterBrowserStatePrefs(pref_registry_.get()); |
+ BrowserStateDependencyManager::GetInstance() |
+ ->RegisterBrowserStatePrefsForServices(this, pref_registry_.get()); |
+ |
+ scoped_refptr<base::SequencedTaskRunner> sequenced_task_runner = |
+ JsonPrefStore::GetTaskRunnerForFile(state_path_, |
+ web::WebThread::GetBlockingPool()); |
+ prefs_ = CreateBrowserStatePrefs(state_path_, sequenced_task_runner.get(), |
+ pref_registry_); |
+ // Register on BrowserState. |
+ user_prefs::UserPrefs::Set(this, prefs_.get()); |
+ |
+ // Migrate obsolete prefs. |
+ PrefService* local_state = GetApplicationContext()->GetLocalState(); |
+ MigrateObsoleteLocalStatePrefs(local_state); |
+ MigrateObsoleteBrowserStatePrefs(prefs_.get()); |
+ |
+ BrowserStateDependencyManager::GetInstance()->CreateBrowserStateServices( |
+ this); |
+ |
+ // It would be nice to use PathService for fetching this directory, but |
+ // the cache directory depends on the browser state stash directory, which |
+ // isn't available to PathService. |
+ base::FilePath base_cache_path; |
+ ios::GetUserCacheDirectory(state_path_, &base_cache_path); |
+ // Always create the cache directory asynchronously. |
+ scoped_refptr<base::SequencedTaskRunner> cache_sequenced_task_runner = |
+ JsonPrefStore::GetTaskRunnerForFile(base_cache_path, |
+ web::WebThread::GetBlockingPool()); |
+ CreateBrowserStateDirectory(cache_sequenced_task_runner.get(), |
+ base_cache_path); |
+ |
+ ssl_config_service_manager_.reset( |
+ ssl_config::SSLConfigServiceManager::CreateDefaultManager( |
+ local_state, |
+ web::WebThread::GetTaskRunnerForThread(web::WebThread::IO))); |
+ |
+ base::FilePath cookie_path = state_path_.Append(kIOSChromeCookieFilename); |
+ base::FilePath channel_id_path = |
+ state_path_.Append(kIOSChromeChannelIDFilename); |
+ base::FilePath cache_path = GetCachePath(base_cache_path); |
+ int cache_max_size = 0; |
+ |
+ // Make sure we initialize the io_data_ after everything else has been |
+ // initialized that we might be reading from the IO thread. |
+ io_data_->Init(cookie_path, channel_id_path, cache_path, cache_max_size, |
+ state_path_); |
+ |
+ // Listen for bookmark model load, to bootstrap the sync service. |
+ bookmarks::BookmarkModel* model = |
+ ios::BookmarkModelFactory::GetForBrowserState(this); |
+ model->AddObserver(new BookmarkModelLoadedObserver(this)); |
+} |
+ |
+ChromeBrowserStateImpl::~ChromeBrowserStateImpl() { |
+ BrowserStateDependencyManager::GetInstance()->DestroyBrowserStateServices( |
+ this); |
+ if (pref_proxy_config_tracker_) |
+ pref_proxy_config_tracker_->DetachFromPrefService(); |
+ DestroyOffTheRecordChromeBrowserState(); |
+} |
+ |
+ios::ChromeBrowserState* |
+ChromeBrowserStateImpl::GetOriginalChromeBrowserState() { |
+ return this; |
+} |
+ |
+ios::ChromeBrowserState* |
+ChromeBrowserStateImpl::GetOffTheRecordChromeBrowserState() { |
+ if (!otr_state_) { |
+ otr_state_.reset( |
+ new OffTheRecordChromeBrowserStateImpl(this, otr_state_path_)); |
+ } |
+ |
+ return otr_state_.get(); |
+} |
+ |
+bool ChromeBrowserStateImpl::HasOffTheRecordChromeBrowserState() const { |
+ return otr_state_; |
+} |
+ |
+void ChromeBrowserStateImpl::DestroyOffTheRecordChromeBrowserState() { |
+ // Tear down both the OTR ChromeBrowserState and the OTR Profile with which |
+ // it is associated. |
+ otr_state_.reset(); |
+} |
+ |
+PrefService* ChromeBrowserStateImpl::GetPrefs() { |
+ DCHECK(prefs_); // Should explicitly be initialized. |
+ return prefs_.get(); |
+} |
+ |
+bool ChromeBrowserStateImpl::IsOffTheRecord() const { |
+ return false; |
+} |
+ |
+base::FilePath ChromeBrowserStateImpl::GetStatePath() const { |
+ return state_path_; |
+} |
+ |
+void ChromeBrowserStateImpl::SetOffTheRecordChromeBrowserState( |
+ scoped_ptr<ios::ChromeBrowserState> otr_state) { |
+ DCHECK(!otr_state_); |
+ otr_state_ = std::move(otr_state); |
+} |
+ |
+PrefService* ChromeBrowserStateImpl::GetOffTheRecordPrefs() { |
+ DCHECK(prefs_); |
+ if (!otr_prefs_) { |
+ otr_prefs_ = CreateIncognitoBrowserStatePrefs(prefs_.get()); |
+ } |
+ return otr_prefs_.get(); |
+} |
+ |
+ChromeBrowserStateIOData* ChromeBrowserStateImpl::GetIOData() { |
+ return io_data_->io_data(); |
+} |
+ |
+net::URLRequestContextGetter* ChromeBrowserStateImpl::CreateRequestContext( |
+ ProtocolHandlerMap* protocol_handlers, |
+ URLRequestInterceptorScopedVector request_interceptors) { |
+ ApplicationContext* application_context = GetApplicationContext(); |
+ return io_data_ |
+ ->CreateMainRequestContextGetter( |
+ protocol_handlers, application_context->GetLocalState(), |
+ application_context->GetIOSChromeIOThread()) |
+ .get(); |
+} |
+ |
+net::URLRequestContextGetter* |
+ChromeBrowserStateImpl::CreateIsolatedRequestContext( |
+ const base::FilePath& partition_path) { |
+ return io_data_->CreateIsolatedAppRequestContextGetter(partition_path).get(); |
+} |
+ |
+void ChromeBrowserStateImpl::ClearNetworkingHistorySince( |
+ base::Time time, |
+ const base::Closure& completion) { |
+ io_data_->ClearNetworkingHistorySince(time, completion); |
+} |
+ |
+PrefProxyConfigTracker* ChromeBrowserStateImpl::GetProxyConfigTracker() { |
+ if (!pref_proxy_config_tracker_) { |
+ pref_proxy_config_tracker_ = |
+ ios::ProxyServiceFactory::CreatePrefProxyConfigTrackerOfProfile( |
+ GetPrefs(), GetApplicationContext()->GetLocalState()); |
+ } |
+ return pref_proxy_config_tracker_.get(); |
+} |
+ |
+net::SSLConfigService* ChromeBrowserStateImpl::GetSSLConfigService() { |
+ // If ssl_config_service_manager_ is null, this typically means that some |
+ // KeyedService is trying to create a RequestContext at startup, |
+ // but SSLConfigServiceManager is not initialized until DoFinalInit() which is |
+ // invoked after all KeyedServices have been initialized (see |
+ // http://crbug.com/171406). |
+ DCHECK(ssl_config_service_manager_) |
+ << "SSLConfigServiceManager is not initialized yet"; |
+ return ssl_config_service_manager_->Get(); |
+} |