OLD | NEW |
(Empty) | |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "ios/chrome/browser/browser_state/chrome_browser_state_impl.h" |
| 6 |
| 7 #include <utility> |
| 8 |
| 9 #include "base/files/file_path.h" |
| 10 #include "base/files/file_util.h" |
| 11 #include "base/logging.h" |
| 12 #include "base/synchronization/waitable_event.h" |
| 13 #include "components/bookmarks/browser/bookmark_model.h" |
| 14 #include "components/keyed_service/ios/browser_state_dependency_manager.h" |
| 15 #include "components/pref_registry/pref_registry_syncable.h" |
| 16 #include "components/prefs/json_pref_store.h" |
| 17 #include "components/prefs/pref_service.h" |
| 18 #include "components/proxy_config/pref_proxy_config_tracker.h" |
| 19 #include "components/syncable_prefs/pref_service_syncable.h" |
| 20 #include "components/user_prefs/user_prefs.h" |
| 21 #include "ios/chrome/browser/application_context.h" |
| 22 #include "ios/chrome/browser/bookmarks/bookmark_model_factory.h" |
| 23 #include "ios/chrome/browser/browser_state/bookmark_model_loaded_observer.h" |
| 24 #include "ios/chrome/browser/browser_state/off_the_record_chrome_browser_state_i
mpl.h" |
| 25 #include "ios/chrome/browser/chrome_constants.h" |
| 26 #include "ios/chrome/browser/chrome_paths_internal.h" |
| 27 #include "ios/chrome/browser/file_metadata_util.h" |
| 28 #include "ios/chrome/browser/net/ios_chrome_url_request_context_getter.h" |
| 29 #include "ios/chrome/browser/net/proxy_service_factory.h" |
| 30 #include "ios/chrome/browser/pref_names.h" |
| 31 #include "ios/chrome/browser/prefs/browser_prefs.h" |
| 32 #include "ios/chrome/browser/prefs/ios_chrome_pref_service_factory.h" |
| 33 #include "ios/web/public/web_thread.h" |
| 34 |
| 35 namespace { |
| 36 |
| 37 // Returns a bool indicating whether the necessary directories were able to be |
| 38 // created (or already existed). |
| 39 bool EnsureBrowserStateDirectoriesCreated(const base::FilePath& path, |
| 40 const base::FilePath& otr_path) { |
| 41 if (!base::PathExists(path) && !base::CreateDirectory(path)) |
| 42 return false; |
| 43 // Create the directory for the OTR stash state now, even though it won't |
| 44 // necessarily be needed: the OTR browser state itself is created |
| 45 // synchronously on an as-needed basis on the UI thread, so creation of its |
| 46 // stash state directory cannot easily be done at that point. |
| 47 if (base::PathExists(otr_path)) |
| 48 return true; |
| 49 if (!base::CreateDirectory(otr_path)) |
| 50 return false; |
| 51 SetSkipSystemBackupAttributeToItem(otr_path, true); |
| 52 return true; |
| 53 } |
| 54 |
| 55 // Task that creates the directory and signal the FILE thread to resume |
| 56 // execution. |
| 57 void CreateDirectoryAndSignal(const base::FilePath& path, |
| 58 base::WaitableEvent* done_creating) { |
| 59 bool success = base::CreateDirectory(path); |
| 60 DCHECK(success); |
| 61 done_creating->Signal(); |
| 62 } |
| 63 |
| 64 // Task that blocks the FILE thread until CreateDirectoryAndSignal() finishes on |
| 65 // blocking I/O pool. |
| 66 void BlockFileThreadOnDirectoryCreate(base::WaitableEvent* done_creating) { |
| 67 done_creating->Wait(); |
| 68 } |
| 69 |
| 70 // Initiates creation of browser state directory on |sequenced_task_runner| and |
| 71 // ensures that FILE thread is blocked until that operation finishes. |
| 72 void CreateBrowserStateDirectory( |
| 73 base::SequencedTaskRunner* sequenced_task_runner, |
| 74 const base::FilePath& path) { |
| 75 base::WaitableEvent* done_creating = new base::WaitableEvent(false, false); |
| 76 sequenced_task_runner->PostTask( |
| 77 FROM_HERE, base::Bind(&CreateDirectoryAndSignal, path, done_creating)); |
| 78 // Block the FILE thread until directory is created on I/O pool to make sure |
| 79 // that we don't attempt any operation until that part completes. |
| 80 web::WebThread::PostTask(web::WebThread::FILE, FROM_HERE, |
| 81 base::Bind(&BlockFileThreadOnDirectoryCreate, |
| 82 base::Owned(done_creating))); |
| 83 } |
| 84 |
| 85 base::FilePath GetCachePath(const base::FilePath& base) { |
| 86 return base.Append(kIOSChromeCacheDirname); |
| 87 } |
| 88 |
| 89 } // namespace |
| 90 |
| 91 ChromeBrowserStateImpl::ChromeBrowserStateImpl(const base::FilePath& path) |
| 92 : state_path_(path), |
| 93 pref_registry_(new user_prefs::PrefRegistrySyncable), |
| 94 io_data_(new ChromeBrowserStateImplIOData::Handle(this)) { |
| 95 otr_state_path_ = state_path_.Append(FILE_PATH_LITERAL("OTR")); |
| 96 |
| 97 bool directories_created = |
| 98 EnsureBrowserStateDirectoriesCreated(state_path_, otr_state_path_); |
| 99 DCHECK(directories_created); |
| 100 |
| 101 RegisterBrowserStatePrefs(pref_registry_.get()); |
| 102 BrowserStateDependencyManager::GetInstance() |
| 103 ->RegisterBrowserStatePrefsForServices(this, pref_registry_.get()); |
| 104 |
| 105 scoped_refptr<base::SequencedTaskRunner> sequenced_task_runner = |
| 106 JsonPrefStore::GetTaskRunnerForFile(state_path_, |
| 107 web::WebThread::GetBlockingPool()); |
| 108 prefs_ = CreateBrowserStatePrefs(state_path_, sequenced_task_runner.get(), |
| 109 pref_registry_); |
| 110 // Register on BrowserState. |
| 111 user_prefs::UserPrefs::Set(this, prefs_.get()); |
| 112 |
| 113 // Migrate obsolete prefs. |
| 114 PrefService* local_state = GetApplicationContext()->GetLocalState(); |
| 115 MigrateObsoleteLocalStatePrefs(local_state); |
| 116 MigrateObsoleteBrowserStatePrefs(prefs_.get()); |
| 117 |
| 118 BrowserStateDependencyManager::GetInstance()->CreateBrowserStateServices( |
| 119 this); |
| 120 |
| 121 // It would be nice to use PathService for fetching this directory, but |
| 122 // the cache directory depends on the browser state stash directory, which |
| 123 // isn't available to PathService. |
| 124 base::FilePath base_cache_path; |
| 125 ios::GetUserCacheDirectory(state_path_, &base_cache_path); |
| 126 // Always create the cache directory asynchronously. |
| 127 scoped_refptr<base::SequencedTaskRunner> cache_sequenced_task_runner = |
| 128 JsonPrefStore::GetTaskRunnerForFile(base_cache_path, |
| 129 web::WebThread::GetBlockingPool()); |
| 130 CreateBrowserStateDirectory(cache_sequenced_task_runner.get(), |
| 131 base_cache_path); |
| 132 |
| 133 ssl_config_service_manager_.reset( |
| 134 ssl_config::SSLConfigServiceManager::CreateDefaultManager( |
| 135 local_state, |
| 136 web::WebThread::GetTaskRunnerForThread(web::WebThread::IO))); |
| 137 |
| 138 base::FilePath cookie_path = state_path_.Append(kIOSChromeCookieFilename); |
| 139 base::FilePath channel_id_path = |
| 140 state_path_.Append(kIOSChromeChannelIDFilename); |
| 141 base::FilePath cache_path = GetCachePath(base_cache_path); |
| 142 int cache_max_size = 0; |
| 143 |
| 144 // Make sure we initialize the io_data_ after everything else has been |
| 145 // initialized that we might be reading from the IO thread. |
| 146 io_data_->Init(cookie_path, channel_id_path, cache_path, cache_max_size, |
| 147 state_path_); |
| 148 |
| 149 // Listen for bookmark model load, to bootstrap the sync service. |
| 150 bookmarks::BookmarkModel* model = |
| 151 ios::BookmarkModelFactory::GetForBrowserState(this); |
| 152 model->AddObserver(new BookmarkModelLoadedObserver(this)); |
| 153 } |
| 154 |
| 155 ChromeBrowserStateImpl::~ChromeBrowserStateImpl() { |
| 156 BrowserStateDependencyManager::GetInstance()->DestroyBrowserStateServices( |
| 157 this); |
| 158 if (pref_proxy_config_tracker_) |
| 159 pref_proxy_config_tracker_->DetachFromPrefService(); |
| 160 DestroyOffTheRecordChromeBrowserState(); |
| 161 } |
| 162 |
| 163 ios::ChromeBrowserState* |
| 164 ChromeBrowserStateImpl::GetOriginalChromeBrowserState() { |
| 165 return this; |
| 166 } |
| 167 |
| 168 ios::ChromeBrowserState* |
| 169 ChromeBrowserStateImpl::GetOffTheRecordChromeBrowserState() { |
| 170 if (!otr_state_) { |
| 171 otr_state_.reset( |
| 172 new OffTheRecordChromeBrowserStateImpl(this, otr_state_path_)); |
| 173 } |
| 174 |
| 175 return otr_state_.get(); |
| 176 } |
| 177 |
| 178 bool ChromeBrowserStateImpl::HasOffTheRecordChromeBrowserState() const { |
| 179 return otr_state_; |
| 180 } |
| 181 |
| 182 void ChromeBrowserStateImpl::DestroyOffTheRecordChromeBrowserState() { |
| 183 // Tear down both the OTR ChromeBrowserState and the OTR Profile with which |
| 184 // it is associated. |
| 185 otr_state_.reset(); |
| 186 } |
| 187 |
| 188 PrefService* ChromeBrowserStateImpl::GetPrefs() { |
| 189 DCHECK(prefs_); // Should explicitly be initialized. |
| 190 return prefs_.get(); |
| 191 } |
| 192 |
| 193 bool ChromeBrowserStateImpl::IsOffTheRecord() const { |
| 194 return false; |
| 195 } |
| 196 |
| 197 base::FilePath ChromeBrowserStateImpl::GetStatePath() const { |
| 198 return state_path_; |
| 199 } |
| 200 |
| 201 void ChromeBrowserStateImpl::SetOffTheRecordChromeBrowserState( |
| 202 scoped_ptr<ios::ChromeBrowserState> otr_state) { |
| 203 DCHECK(!otr_state_); |
| 204 otr_state_ = std::move(otr_state); |
| 205 } |
| 206 |
| 207 PrefService* ChromeBrowserStateImpl::GetOffTheRecordPrefs() { |
| 208 DCHECK(prefs_); |
| 209 if (!otr_prefs_) { |
| 210 otr_prefs_ = CreateIncognitoBrowserStatePrefs(prefs_.get()); |
| 211 } |
| 212 return otr_prefs_.get(); |
| 213 } |
| 214 |
| 215 ChromeBrowserStateIOData* ChromeBrowserStateImpl::GetIOData() { |
| 216 return io_data_->io_data(); |
| 217 } |
| 218 |
| 219 net::URLRequestContextGetter* ChromeBrowserStateImpl::CreateRequestContext( |
| 220 ProtocolHandlerMap* protocol_handlers, |
| 221 URLRequestInterceptorScopedVector request_interceptors) { |
| 222 ApplicationContext* application_context = GetApplicationContext(); |
| 223 return io_data_ |
| 224 ->CreateMainRequestContextGetter( |
| 225 protocol_handlers, application_context->GetLocalState(), |
| 226 application_context->GetIOSChromeIOThread()) |
| 227 .get(); |
| 228 } |
| 229 |
| 230 net::URLRequestContextGetter* |
| 231 ChromeBrowserStateImpl::CreateIsolatedRequestContext( |
| 232 const base::FilePath& partition_path) { |
| 233 return io_data_->CreateIsolatedAppRequestContextGetter(partition_path).get(); |
| 234 } |
| 235 |
| 236 void ChromeBrowserStateImpl::ClearNetworkingHistorySince( |
| 237 base::Time time, |
| 238 const base::Closure& completion) { |
| 239 io_data_->ClearNetworkingHistorySince(time, completion); |
| 240 } |
| 241 |
| 242 PrefProxyConfigTracker* ChromeBrowserStateImpl::GetProxyConfigTracker() { |
| 243 if (!pref_proxy_config_tracker_) { |
| 244 pref_proxy_config_tracker_ = |
| 245 ios::ProxyServiceFactory::CreatePrefProxyConfigTrackerOfProfile( |
| 246 GetPrefs(), GetApplicationContext()->GetLocalState()); |
| 247 } |
| 248 return pref_proxy_config_tracker_.get(); |
| 249 } |
| 250 |
| 251 net::SSLConfigService* ChromeBrowserStateImpl::GetSSLConfigService() { |
| 252 // If ssl_config_service_manager_ is null, this typically means that some |
| 253 // KeyedService is trying to create a RequestContext at startup, |
| 254 // but SSLConfigServiceManager is not initialized until DoFinalInit() which is |
| 255 // invoked after all KeyedServices have been initialized (see |
| 256 // http://crbug.com/171406). |
| 257 DCHECK(ssl_config_service_manager_) |
| 258 << "SSLConfigServiceManager is not initialized yet"; |
| 259 return ssl_config_service_manager_->Get(); |
| 260 } |
OLD | NEW |