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

Side by Side Diff: ios/chrome/browser/browser_state/test_chrome_browser_state.cc

Issue 1664823003: Upstream ChromeBrowserState sub-classes. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Address comments Created 4 years, 10 months 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
OLDNEW
(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/test_chrome_browser_state.h"
6
7 #include <utility>
8
9 #include "base/base_paths.h"
10 #include "base/files/file_util.h"
11 #include "base/logging.h"
12 #include "base/macros.h"
13 #include "base/message_loop/message_loop.h"
14 #include "base/path_service.h"
15 #include "base/run_loop.h"
16 #include "base/thread_task_runner_handle.h"
17 #include "components/bookmarks/browser/bookmark_model.h"
18 #include "components/bookmarks/common/bookmark_constants.h"
19 #include "components/history/core/browser/history_constants.h"
20 #include "components/history/core/browser/history_database_params.h"
21 #include "components/history/core/browser/history_service.h"
22 #include "components/history/core/browser/top_sites.h"
23 #include "components/history/core/browser/visit_delegate.h"
24 #include "components/history/ios/browser/history_database_helper.h"
25 #include "components/keyed_service/core/service_access_type.h"
26 #include "components/keyed_service/ios/browser_state_dependency_manager.h"
27 #include "components/syncable_prefs/pref_service_syncable.h"
28 #include "components/syncable_prefs/testing_pref_service_syncable.h"
29 #include "components/user_prefs/user_prefs.h"
30 #include "components/webdata_services/web_data_service_wrapper.h"
31 #include "ios/chrome/browser/application_context.h"
32 #include "ios/chrome/browser/autocomplete/in_memory_url_index_factory.h"
33 #include "ios/chrome/browser/bookmarks/bookmark_client_impl.h"
34 #include "ios/chrome/browser/bookmarks/bookmark_model_factory.h"
35 #include "ios/chrome/browser/browser_state/browser_state_keyed_service_factories .h"
36 #include "ios/chrome/browser/history/history_client_impl.h"
37 #include "ios/chrome/browser/history/history_service_factory.h"
38 #include "ios/chrome/browser/history/top_sites_factory.h"
39 #include "ios/chrome/browser/history/web_history_service_factory.h"
40 #include "ios/chrome/browser/pref_names.h"
41 #include "ios/chrome/browser/prefs/browser_prefs.h"
42 #include "ios/chrome/browser/prefs/ios_chrome_pref_service_factory.h"
43 #include "ios/chrome/browser/sync/glue/sync_start_util.h"
44 #include "ios/chrome/browser/web_data_service_factory.h"
45 #include "ios/public/provider/chrome/browser/chrome_browser_provider.h"
46 #include "ios/web/public/web_thread.h"
47 #include "net/url_request/url_request_test_util.h"
48
49 namespace {
50 scoped_ptr<KeyedService> BuildHistoryService(web::BrowserState* context) {
51 ios::ChromeBrowserState* browser_state =
52 ios::ChromeBrowserState::FromBrowserState(context);
53 return make_scoped_ptr(new history::HistoryService(
54 make_scoped_ptr(new HistoryClientImpl(
55 ios::BookmarkModelFactory::GetForBrowserState(browser_state))),
56 nullptr));
57 }
58
59 scoped_ptr<KeyedService> BuildBookmarkModel(web::BrowserState* context) {
60 ios::ChromeBrowserState* browser_state =
61 ios::ChromeBrowserState::FromBrowserState(context);
62 scoped_ptr<bookmarks::BookmarkModel> bookmark_model(
63 new bookmarks::BookmarkModel(
64 make_scoped_ptr(new BookmarkClientImpl(browser_state))));
65 bookmark_model->Load(
66 browser_state->GetPrefs(),
67 browser_state->GetPrefs()->GetString(prefs::kAcceptLanguages),
68 browser_state->GetStatePath(), browser_state->GetIOTaskRunner(),
69 web::WebThread::GetTaskRunnerForThread(web::WebThread::UI));
70 return std::move(bookmark_model);
71 }
72
73 void NotReachedErrorCallback(WebDataServiceWrapper::ErrorType error_type,
74 sql::InitStatus status) {
75 NOTREACHED();
76 }
77
78 scoped_ptr<KeyedService> BuildWebDataService(web::BrowserState* context) {
79 const base::FilePath& browser_state_path = context->GetStatePath();
80 return make_scoped_ptr(new WebDataServiceWrapper(
81 browser_state_path, GetApplicationContext()->GetApplicationLocale(),
82 web::WebThread::GetTaskRunnerForThread(web::WebThread::UI),
83 web::WebThread::GetTaskRunnerForThread(web::WebThread::DB),
84 ios::sync_start_util::GetFlareForSyncableService(browser_state_path),
85 &NotReachedErrorCallback));
86 }
87
88 base::FilePath CreateTempBrowserStateDir(base::ScopedTempDir* temp_dir) {
89 DCHECK(temp_dir);
90 if (!temp_dir->CreateUniqueTempDir()) {
91 // Fallback logic in case we fail to create unique temporary directory.
92 LOG(ERROR) << "Failed to create unique temporary directory.";
93 base::FilePath system_tmp_dir;
94 bool success = PathService::Get(base::DIR_TEMP, &system_tmp_dir);
95
96 // We're severly screwed if we can't get the system temporary
97 // directory. Die now to avoid writing to the filesystem root
98 // or other bad places.
99 CHECK(success);
100
101 base::FilePath fallback_dir(
102 system_tmp_dir.Append(FILE_PATH_LITERAL("TestChromeBrowserStatePath")));
103 base::DeleteFile(fallback_dir, true);
104 base::CreateDirectory(fallback_dir);
105 if (!temp_dir->Set(fallback_dir)) {
106 // That shouldn't happen, but if it does, try to recover.
107 LOG(ERROR) << "Failed to use a fallback temporary directory.";
108
109 // We're screwed if this fails, see CHECK above.
110 CHECK(temp_dir->Set(system_tmp_dir));
111 }
112 }
113 return temp_dir->path();
114 }
115 } // namespace
116
117 TestChromeBrowserState::TestChromeBrowserState(
118 TestChromeBrowserState* original_browser_state)
119 : testing_prefs_(nullptr),
120 otr_browser_state_(nullptr),
121 original_browser_state_(original_browser_state) {
122 // Not calling Init() here as the bi-directional link between original and
123 // off-the-record TestChromeBrowserState must be established before this
124 // method can be called.
125 DCHECK(original_browser_state_);
126 }
127
128 TestChromeBrowserState::TestChromeBrowserState(
129 const base::FilePath& path,
130 scoped_ptr<syncable_prefs::PrefServiceSyncable> prefs,
131 const TestingFactories& testing_factories,
132 const RefcountedTestingFactories& refcounted_testing_factories)
133 : state_path_(path),
134 prefs_(std::move(prefs)),
135 testing_prefs_(nullptr),
136 otr_browser_state_(nullptr),
137 original_browser_state_(nullptr) {
138 Init();
139
140 for (const auto& pair : testing_factories) {
141 pair.first->SetTestingFactory(this, pair.second);
142 }
143
144 for (const auto& pair : refcounted_testing_factories) {
145 pair.first->SetTestingFactory(this, pair.second);
146 }
147 }
148
149 TestChromeBrowserState::~TestChromeBrowserState() {
150 // If this TestChromeBrowserState owns an incognito TestChromeBrowserState,
151 // tear it down first.
152 otr_browser_state_.reset();
153
154 BrowserStateDependencyManager::GetInstance()->DestroyBrowserStateServices(
155 this);
156 }
157
158 void TestChromeBrowserState::Init() {
159 // If threads have been initialized, we should be on the UI thread.
160 DCHECK(!web::WebThread::IsThreadInitialized(web::WebThread::UI) ||
161 web::WebThread::CurrentlyOn(web::WebThread::UI));
162
163 if (state_path_.empty())
164 state_path_ = CreateTempBrowserStateDir(&temp_dir_);
165
166 if (IsOffTheRecord())
167 state_path_ = state_path_.Append(FILE_PATH_LITERAL("OTR"));
168
169 if (!base::PathExists(state_path_))
170 base::CreateDirectory(state_path_);
171
172 // Normally this would happen during browser startup, but for tests we need to
173 // trigger creation of BrowserState-related services.
174 EnsureBrowserStateKeyedServiceFactoriesBuilt();
175 if (ios::GetChromeBrowserProvider())
176 ios::GetChromeBrowserProvider()->AssertBrowserContextKeyedFactoriesBuilt();
177
178 if (prefs_) {
179 // If user passed a custom PrefServiceSyncable, then leave |testing_prefs_|
180 // unset as it is not possible to determine its type.
181 } else if (IsOffTheRecord()) {
182 // This leaves |testing_prefs_| unset as CreateIncognitoBrowserStatePrefs()
183 // does not return a TestingPrefServiceSyncable.
184 DCHECK(original_browser_state_);
185 prefs_ =
186 CreateIncognitoBrowserStatePrefs(original_browser_state_->prefs_.get());
187 } else {
188 testing_prefs_ = new syncable_prefs::TestingPrefServiceSyncable();
189 RegisterBrowserStatePrefs(testing_prefs_->registry());
190 prefs_.reset(testing_prefs_);
191 }
192 user_prefs::UserPrefs::Set(this, prefs_.get());
193
194 // Prefs for incognito TestChromeBrowserState are set in
195 // CreateIncognitoBrowserStatePrefs().
196 if (!IsOffTheRecord()) {
197 user_prefs::PrefRegistrySyncable* pref_registry =
198 static_cast<user_prefs::PrefRegistrySyncable*>(
199 prefs_->DeprecatedGetPrefRegistry());
200 BrowserStateDependencyManager::GetInstance()
201 ->RegisterBrowserStatePrefsForServices(this, pref_registry);
202 }
203
204 BrowserStateDependencyManager::GetInstance()
205 ->CreateBrowserStateServicesForTest(this);
206 }
207
208 bool TestChromeBrowserState::IsOffTheRecord() const {
209 return original_browser_state_ != nullptr;
210 }
211
212 base::FilePath TestChromeBrowserState::GetStatePath() const {
213 if (!IsOffTheRecord())
214 return state_path_;
215
216 base::FilePath otr_stash_state_path =
217 state_path_.Append(FILE_PATH_LITERAL("OTR"));
218 if (!base::PathExists(otr_stash_state_path))
219 base::CreateDirectory(otr_stash_state_path);
220 return otr_stash_state_path;
221 }
222
223 scoped_refptr<base::SequencedTaskRunner>
224 TestChromeBrowserState::GetIOTaskRunner() {
225 return base::MessageLoop::current()->task_runner();
226 }
227
228 ios::ChromeBrowserState*
229 TestChromeBrowserState::GetOriginalChromeBrowserState() {
230 if (IsOffTheRecord())
231 return original_browser_state_;
232 return this;
233 }
234
235 bool TestChromeBrowserState::HasOffTheRecordChromeBrowserState() const {
236 return otr_browser_state_ != nullptr;
237 }
238
239 ios::ChromeBrowserState*
240 TestChromeBrowserState::GetOffTheRecordChromeBrowserState() {
241 if (IsOffTheRecord())
242 return this;
243
244 if (!otr_browser_state_) {
245 otr_browser_state_.reset(new TestChromeBrowserState(this));
246 otr_browser_state_->Init();
247 }
248
249 return otr_browser_state_.get();
250 }
251
252 PrefProxyConfigTracker* TestChromeBrowserState::GetProxyConfigTracker() {
253 return nullptr;
254 }
255
256 net::SSLConfigService* TestChromeBrowserState::GetSSLConfigService() {
257 return nullptr;
258 }
259
260 PrefService* TestChromeBrowserState::GetPrefs() {
261 return prefs_.get();
262 }
263
264 PrefService* TestChromeBrowserState::GetOffTheRecordPrefs() {
265 return nullptr;
266 }
267
268 ChromeBrowserStateIOData* TestChromeBrowserState::GetIOData() {
269 return nullptr;
270 }
271
272 void TestChromeBrowserState::ClearNetworkingHistorySince(
273 base::Time time,
274 const base::Closure& completion) {
275 if (!completion.is_null())
276 completion.Run();
277 }
278
279 net::URLRequestContextGetter* TestChromeBrowserState::CreateRequestContext(
280 ProtocolHandlerMap* protocol_handlers,
281 URLRequestInterceptorScopedVector request_interceptors) {
282 return new net::TestURLRequestContextGetter(
283 web::WebThread::GetTaskRunnerForThread(web::WebThread::IO));
284 }
285
286 net::URLRequestContextGetter*
287 TestChromeBrowserState::CreateIsolatedRequestContext(
288 const base::FilePath& partition_path) {
289 return nullptr;
290 }
291
292 TestChromeBrowserState* TestChromeBrowserState::AsTestChromeBrowserState() {
293 return this;
294 }
295
296 void TestChromeBrowserState::CreateWebDataService() {
297 ignore_result(
298 ios::WebDataServiceFactory::GetInstance()->SetTestingFactoryAndUse(
299 this, &BuildWebDataService));
300
301 // Wait a bit after creating the WebDataService to allow the initialisation
302 // to complete (otherwise the TestChromeBrowserState may be destroyed before
303 // initialisation of the database is complete which leads to SQL init errors).
304 base::RunLoop run_loop;
305 run_loop.RunUntilIdle();
306 }
307
308 void TestChromeBrowserState::CreateBookmarkModel(bool delete_file) {
309 if (delete_file) {
310 base::DeleteFile(GetOriginalChromeBrowserState()->GetStatePath().Append(
311 bookmarks::kBookmarksFileName),
312 false /* recursive */);
313 }
314 ignore_result(
315 ios::BookmarkModelFactory::GetInstance()->SetTestingFactoryAndUse(
316 this, &BuildBookmarkModel));
317 }
318
319 bool TestChromeBrowserState::CreateHistoryService(bool delete_file) {
320 // Ensure that no HistoryService exists before creating a new one.
321 DestroyHistoryService();
322
323 if (delete_file) {
324 base::FilePath path =
325 GetOriginalChromeBrowserState()->GetStatePath().Append(
326 history::kHistoryFilename);
327 if (!base::DeleteFile(path, false) && base::PathExists(path))
328 return false;
329 }
330
331 // Create and initialize the HistoryService, but destroy it if the init fails.
332 history::HistoryService* history_service =
333 static_cast<history::HistoryService*>(
334 ios::HistoryServiceFactory::GetInstance()->SetTestingFactoryAndUse(
335 this, &BuildHistoryService));
336 if (!history_service->Init(
337 GetPrefs()->GetString(prefs::kAcceptLanguages),
338 history::HistoryDatabaseParamsForPath(
339 GetOriginalChromeBrowserState()->GetStatePath()))) {
340 ios::HistoryServiceFactory::GetInstance()->SetTestingFactory(this, nullptr);
341 return false;
342 }
343
344 // Some tests expect that CreateHistoryService() will also make the
345 // InMemoryURLIndex available.
346 ios::InMemoryURLIndexFactory::GetInstance()->SetTestingFactory(
347 this, ios::InMemoryURLIndexFactory::GetDefaultFactory());
348 // Disable WebHistoryService by default, since it makes network requests.
349 ios::WebHistoryServiceFactory::GetInstance()->SetTestingFactory(this,
350 nullptr);
351
352 return true;
353 }
354
355 void TestChromeBrowserState::DestroyHistoryService() {
356 history::HistoryService* history_service =
357 ios::HistoryServiceFactory::GetInstance()->GetForBrowserStateIfExists(
358 this, ServiceAccessType::EXPLICIT_ACCESS);
359 if (!history_service)
360 return;
361
362 history_service->ClearCachedDataForContextID(0);
363 history_service->SetOnBackendDestroyTask(
364 base::MessageLoop::QuitWhenIdleClosure());
365 history_service->Shutdown();
366 history_service = nullptr;
367
368 // Resetting the testing factory force the destruction of the current
369 // HistoryService instance associated with the TestChromeBrowserState.
370 ios::HistoryServiceFactory::GetInstance()->SetTestingFactory(this, nullptr);
371
372 // Wait for the backend class to terminate before deleting the files and
373 // moving to the next test. Note: if this never terminates, somebody is
374 // probably leaking a reference to the history backend, so it never calls
375 // our destroy task.
376 base::MessageLoop::current()->Run();
377
378 // Make sure we don't have any event pending that could disrupt the next
379 // test.
380 base::ThreadTaskRunnerHandle::Get()->PostTask(
381 FROM_HERE, base::MessageLoop::QuitWhenIdleClosure());
382 base::MessageLoop::current()->Run();
383 }
384
385 syncable_prefs::TestingPrefServiceSyncable*
386 TestChromeBrowserState::GetTestingPrefService() {
387 DCHECK(prefs_);
388 DCHECK(testing_prefs_);
389 return testing_prefs_;
390 }
391
392 TestChromeBrowserState::Builder::Builder() : build_called_(false) {}
393
394 TestChromeBrowserState::Builder::~Builder() {}
395
396 void TestChromeBrowserState::Builder::AddTestingFactory(
397 BrowserStateKeyedServiceFactory* service_factory,
398 BrowserStateKeyedServiceFactory::TestingFactoryFunction cb) {
399 DCHECK(!build_called_);
400 testing_factories_.push_back(std::make_pair(service_factory, cb));
401 }
402
403 void TestChromeBrowserState::Builder::AddTestingFactory(
404 RefcountedBrowserStateKeyedServiceFactory* service_factory,
405 RefcountedBrowserStateKeyedServiceFactory::TestingFactoryFunction cb) {
406 DCHECK(!build_called_);
407 refcounted_testing_factories_.push_back(std::make_pair(service_factory, cb));
408 }
409
410 void TestChromeBrowserState::Builder::SetPath(const base::FilePath& path) {
411 DCHECK(!build_called_);
412 state_path_ = path;
413 }
414
415 void TestChromeBrowserState::Builder::SetPrefService(
416 scoped_ptr<syncable_prefs::PrefServiceSyncable> prefs) {
417 DCHECK(!build_called_);
418 pref_service_ = std::move(prefs);
419 }
420
421 scoped_ptr<TestChromeBrowserState> TestChromeBrowserState::Builder::Build() {
422 DCHECK(!build_called_);
423 return make_scoped_ptr(new TestChromeBrowserState(
424 state_path_, std::move(pref_service_), testing_factories_,
425 refcounted_testing_factories_));
426 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698