| // Copyright (c) 2012 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 "chrome/test/base/testing_profile.h" |
| |
| #include "base/base_paths.h" |
| #include "base/command_line.h" |
| #include "base/files/file_util.h" |
| #include "base/message_loop/message_loop_proxy.h" |
| #include "base/path_service.h" |
| #include "base/prefs/testing_pref_store.h" |
| #include "base/run_loop.h" |
| #include "base/strings/string_number_conversions.h" |
| #include "chrome/browser/autocomplete/autocomplete_classifier.h" |
| #include "chrome/browser/autocomplete/in_memory_url_index.h" |
| #include "chrome/browser/autocomplete/in_memory_url_index_factory.h" |
| #include "chrome/browser/bookmarks/bookmark_model_factory.h" |
| #include "chrome/browser/bookmarks/chrome_bookmark_client.h" |
| #include "chrome/browser/bookmarks/chrome_bookmark_client_factory.h" |
| #include "chrome/browser/browser_process.h" |
| #include "chrome/browser/chrome_notification_types.h" |
| #include "chrome/browser/favicon/chrome_fallback_icon_client_factory.h" |
| #include "chrome/browser/favicon/chrome_favicon_client_factory.h" |
| #include "chrome/browser/favicon/fallback_icon_service_factory.h" |
| #include "chrome/browser/favicon/favicon_service_factory.h" |
| #include "chrome/browser/history/chrome_history_client.h" |
| #include "chrome/browser/history/chrome_history_client_factory.h" |
| #include "chrome/browser/history/history_service_factory.h" |
| #include "chrome/browser/history/top_sites_factory.h" |
| #include "chrome/browser/history/top_sites_impl.h" |
| #include "chrome/browser/history/web_history_service_factory.h" |
| #include "chrome/browser/net/pref_proxy_config_tracker.h" |
| #include "chrome/browser/net/proxy_service_factory.h" |
| #include "chrome/browser/notifications/desktop_notification_service.h" |
| #include "chrome/browser/notifications/desktop_notification_service_factory.h" |
| #include "chrome/browser/policy/profile_policy_connector.h" |
| #include "chrome/browser/policy/profile_policy_connector_factory.h" |
| #include "chrome/browser/prefs/browser_prefs.h" |
| #include "chrome/browser/prefs/pref_service_syncable.h" |
| #include "chrome/browser/prerender/prerender_manager.h" |
| #include "chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.h" |
| #include "chrome/browser/profiles/profile_manager.h" |
| #include "chrome/browser/profiles/storage_partition_descriptor.h" |
| #include "chrome/browser/search_engines/template_url_fetcher_factory.h" |
| #include "chrome/browser/sync/glue/sync_start_util.h" |
| #include "chrome/browser/ui/zoom/chrome_zoom_level_prefs.h" |
| #include "chrome/browser/webdata/web_data_service_factory.h" |
| #include "chrome/common/chrome_constants.h" |
| #include "chrome/common/chrome_switches.h" |
| #include "chrome/common/pref_names.h" |
| #include "chrome/common/url_constants.h" |
| #include "chrome/test/base/history_index_restore_observer.h" |
| #include "chrome/test/base/testing_pref_service_syncable.h" |
| #include "components/autofill/core/browser/webdata/autofill_webdata_service.h" |
| #include "components/bookmarks/browser/bookmark_model.h" |
| #include "components/bookmarks/common/bookmark_constants.h" |
| #include "components/content_settings/core/browser/host_content_settings_map.h" |
| #include "components/favicon/core/fallback_icon_service.h" |
| #include "components/favicon/core/favicon_service.h" |
| #include "components/history/content/browser/content_visit_delegate.h" |
| #include "components/history/content/browser/history_database_helper.h" |
| #include "components/history/core/browser/history_backend.h" |
| #include "components/history/core/browser/history_constants.h" |
| #include "components/history/core/browser/history_database_params.h" |
| #include "components/history/core/browser/history_db_task.h" |
| #include "components/history/core/browser/history_service.h" |
| #include "components/history/core/browser/top_sites.h" |
| #include "components/history/core/browser/top_sites_observer.h" |
| #include "components/keyed_service/content/browser_context_dependency_manager.h" |
| #include "components/keyed_service/core/refcounted_keyed_service.h" |
| #include "components/policy/core/common/policy_service.h" |
| #include "components/ui/zoom/zoom_event_manager.h" |
| #include "components/user_prefs/user_prefs.h" |
| #include "components/webdata_services/web_data_service_wrapper.h" |
| #include "content/public/browser/browser_thread.h" |
| #include "content/public/browser/cookie_store_factory.h" |
| #include "content/public/browser/notification_service.h" |
| #include "content/public/browser/render_process_host.h" |
| #include "content/public/browser/storage_partition.h" |
| #include "content/public/browser/zoom_level_delegate.h" |
| #include "content/public/test/mock_resource_context.h" |
| #include "content/public/test/test_utils.h" |
| #include "extensions/common/constants.h" |
| #include "net/cookies/cookie_monster.h" |
| #include "net/url_request/url_request_context.h" |
| #include "net/url_request/url_request_context_getter.h" |
| #include "net/url_request/url_request_test_util.h" |
| #include "testing/gmock/include/gmock/gmock.h" |
| |
| #if defined(ENABLE_CONFIGURATION_POLICY) |
| #include "chrome/browser/policy/schema_registry_service.h" |
| #include "chrome/browser/policy/schema_registry_service_factory.h" |
| #include "components/policy/core/common/configuration_policy_provider.h" |
| #include "components/policy/core/common/policy_service_impl.h" |
| #include "components/policy/core/common/schema.h" |
| #else |
| #include "components/policy/core/common/policy_service_stub.h" |
| #endif // defined(ENABLE_CONFIGURATION_POLICY) |
| |
| #if defined(ENABLE_EXTENSIONS) |
| #include "chrome/browser/extensions/extension_service.h" |
| #include "chrome/browser/extensions/extension_special_storage_policy.h" |
| #include "chrome/browser/extensions/extension_system_factory.h" |
| #include "chrome/browser/extensions/test_extension_system.h" |
| #include "extensions/browser/extension_system.h" |
| #include "extensions/browser/guest_view/guest_view_manager.h" |
| #endif |
| |
| #if defined(OS_ANDROID) |
| #include "chrome/browser/signin/android_profile_oauth2_token_service.h" |
| #endif |
| |
| #if defined(ENABLE_SUPERVISED_USERS) |
| #include "chrome/browser/supervised_user/supervised_user_constants.h" |
| #include "chrome/browser/supervised_user/supervised_user_settings_service.h" |
| #include "chrome/browser/supervised_user/supervised_user_settings_service_factory.h" |
| #endif |
| |
| using base::Time; |
| using bookmarks::BookmarkModel; |
| using content::BrowserThread; |
| using content::DownloadManagerDelegate; |
| using testing::NiceMock; |
| using testing::Return; |
| |
| namespace { |
| |
| // TopSitesImpl::Shutdown schedules some tasks (from TopSitesBackend) that |
| // need to be run to properly shutdown. Run all pending tasks now. This is |
| // normally handled by browser_process shutdown. |
| |
| void CleanupAfterTopSitesDestroyed() { |
| if (base::MessageLoop::current()) |
| base::MessageLoop::current()->RunUntilIdle(); |
| } |
| |
| // Returns true if a TopSites service has been registered for |profile|. |
| bool HasTopSites(Profile* profile) { |
| return !!TopSitesFactory::GetInstance()->GetForProfileIfExists(profile); |
| } |
| |
| // Used to make sure TopSites has finished loading |
| class WaitTopSitesLoadedObserver : public history::TopSitesObserver { |
| public: |
| explicit WaitTopSitesLoadedObserver(content::MessageLoopRunner* runner) |
| : runner_(runner) {} |
| void TopSitesLoaded(history::TopSites* top_sites) override { |
| runner_->Quit(); |
| } |
| void TopSitesChanged(history::TopSites* top_sites) override {} |
| |
| private: |
| // weak |
| content::MessageLoopRunner* runner_; |
| }; |
| |
| // Task used to make sure history has finished processing a request. Intended |
| // for use with BlockUntilHistoryProcessesPendingRequests. |
| |
| class QuittingHistoryDBTask : public history::HistoryDBTask { |
| public: |
| QuittingHistoryDBTask() {} |
| |
| bool RunOnDBThread(history::HistoryBackend* backend, |
| history::HistoryDatabase* db) override { |
| return true; |
| } |
| |
| void DoneRunOnMainThread() override { base::MessageLoop::current()->Quit(); } |
| |
| private: |
| ~QuittingHistoryDBTask() override {} |
| |
| DISALLOW_COPY_AND_ASSIGN(QuittingHistoryDBTask); |
| }; |
| |
| class TestExtensionURLRequestContext : public net::URLRequestContext { |
| public: |
| TestExtensionURLRequestContext() { |
| net::CookieMonster* cookie_monster = |
| content::CreateCookieStore(content::CookieStoreConfig())-> |
| GetCookieMonster(); |
| const char* const schemes[] = {extensions::kExtensionScheme}; |
| cookie_monster->SetCookieableSchemes(schemes, arraysize(schemes)); |
| set_cookie_store(cookie_monster); |
| } |
| |
| ~TestExtensionURLRequestContext() override { AssertNoURLRequests(); } |
| }; |
| |
| class TestExtensionURLRequestContextGetter |
| : public net::URLRequestContextGetter { |
| public: |
| net::URLRequestContext* GetURLRequestContext() override { |
| if (!context_.get()) |
| context_.reset(new TestExtensionURLRequestContext()); |
| return context_.get(); |
| } |
| scoped_refptr<base::SingleThreadTaskRunner> GetNetworkTaskRunner() |
| const override { |
| return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO); |
| } |
| |
| protected: |
| ~TestExtensionURLRequestContextGetter() override {} |
| |
| private: |
| scoped_ptr<net::URLRequestContext> context_; |
| }; |
| |
| #if defined(ENABLE_NOTIFICATIONS) |
| KeyedService* CreateTestDesktopNotificationService( |
| content::BrowserContext* profile) { |
| return new DesktopNotificationService(static_cast<Profile*>(profile)); |
| } |
| #endif |
| |
| KeyedService* BuildFallbackIconService(content::BrowserContext* context) { |
| Profile* profile = Profile::FromBrowserContext(context); |
| return new FallbackIconService( |
| ChromeFallbackIconClientFactory::GetForBrowserContext(profile)); |
| } |
| |
| KeyedService* BuildFaviconService(content::BrowserContext* context) { |
| Profile* profile = Profile::FromBrowserContext(context); |
| return new FaviconService(ChromeFaviconClientFactory::GetForProfile(profile), |
| HistoryServiceFactory::GetForProfile( |
| profile, ServiceAccessType::EXPLICIT_ACCESS)); |
| } |
| |
| KeyedService* BuildHistoryService(content::BrowserContext* context) { |
| Profile* profile = Profile::FromBrowserContext(context); |
| history::HistoryService* history_service = new history::HistoryService( |
| ChromeHistoryClientFactory::GetForProfile(profile), |
| scoped_ptr<history::VisitDelegate>( |
| new history::ContentVisitDelegate(profile))); |
| return history_service; |
| } |
| |
| KeyedService* BuildInMemoryURLIndex(content::BrowserContext* context) { |
| Profile* profile = Profile::FromBrowserContext(context); |
| InMemoryURLIndex* in_memory_url_index = new InMemoryURLIndex( |
| BookmarkModelFactory::GetForProfile(profile), |
| HistoryServiceFactory::GetForProfile(profile, |
| ServiceAccessType::IMPLICIT_ACCESS), |
| profile->GetPath(), |
| profile->GetPrefs()->GetString(prefs::kAcceptLanguages)); |
| in_memory_url_index->Init(); |
| return in_memory_url_index; |
| } |
| |
| KeyedService* BuildBookmarkModel(content::BrowserContext* context) { |
| Profile* profile = static_cast<Profile*>(context); |
| ChromeBookmarkClient* bookmark_client = |
| ChromeBookmarkClientFactory::GetForProfile(profile); |
| BookmarkModel* bookmark_model = new BookmarkModel(bookmark_client); |
| bookmark_client->Init(bookmark_model); |
| bookmark_model->Load(profile->GetPrefs(), |
| profile->GetPrefs()->GetString(prefs::kAcceptLanguages), |
| profile->GetPath(), |
| profile->GetIOTaskRunner(), |
| content::BrowserThread::GetMessageLoopProxyForThread( |
| content::BrowserThread::UI)); |
| return bookmark_model; |
| } |
| |
| KeyedService* BuildChromeBookmarkClient( |
| content::BrowserContext* context) { |
| return new ChromeBookmarkClient(static_cast<Profile*>(context)); |
| } |
| |
| KeyedService* BuildChromeHistoryClient( |
| content::BrowserContext* context) { |
| Profile* profile = static_cast<Profile*>(context); |
| return new ChromeHistoryClient(BookmarkModelFactory::GetForProfile(profile)); |
| } |
| |
| void TestProfileErrorCallback(WebDataServiceWrapper::ErrorType error_type, |
| sql::InitStatus status) { |
| NOTREACHED(); |
| } |
| |
| KeyedService* BuildWebDataService(content::BrowserContext* context) { |
| const base::FilePath& context_path = context->GetPath(); |
| return new WebDataServiceWrapper( |
| context_path, g_browser_process->GetApplicationLocale(), |
| BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI), |
| BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB), |
| sync_start_util::GetFlareForSyncableService(context_path), |
| &TestProfileErrorCallback); |
| } |
| |
| scoped_refptr<RefcountedKeyedService> BuildTopSites( |
| content::BrowserContext* profile) { |
| history::TopSitesImpl* top_sites = new history::TopSitesImpl( |
| static_cast<Profile*>(profile), history::PrepopulatedPageList()); |
| top_sites->Init( |
| profile->GetPath().Append(chrome::kTopSitesFilename), |
| BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB)); |
| return make_scoped_refptr(top_sites); |
| } |
| |
| } // namespace |
| |
| // static |
| #if defined(OS_CHROMEOS) |
| // Must be kept in sync with |
| // ChromeBrowserMainPartsChromeos::PreEarlyInitialization. |
| const char TestingProfile::kTestUserProfileDir[] = "test-user"; |
| #else |
| const char TestingProfile::kTestUserProfileDir[] = "Default"; |
| #endif |
| |
| TestingProfile::TestingProfile() |
| : start_time_(Time::Now()), |
| testing_prefs_(NULL), |
| force_incognito_(false), |
| original_profile_(NULL), |
| guest_session_(false), |
| last_session_exited_cleanly_(true), |
| browser_context_dependency_manager_( |
| BrowserContextDependencyManager::GetInstance()), |
| resource_context_(NULL), |
| delegate_(NULL) { |
| CreateTempProfileDir(); |
| profile_path_ = temp_dir_.path(); |
| |
| Init(); |
| FinishInit(); |
| } |
| |
| TestingProfile::TestingProfile(const base::FilePath& path) |
| : start_time_(Time::Now()), |
| testing_prefs_(NULL), |
| force_incognito_(false), |
| original_profile_(NULL), |
| guest_session_(false), |
| last_session_exited_cleanly_(true), |
| profile_path_(path), |
| browser_context_dependency_manager_( |
| BrowserContextDependencyManager::GetInstance()), |
| resource_context_(NULL), |
| delegate_(NULL) { |
| Init(); |
| FinishInit(); |
| } |
| |
| TestingProfile::TestingProfile(const base::FilePath& path, |
| Delegate* delegate) |
| : start_time_(Time::Now()), |
| testing_prefs_(NULL), |
| force_incognito_(false), |
| original_profile_(NULL), |
| guest_session_(false), |
| last_session_exited_cleanly_(true), |
| profile_path_(path), |
| browser_context_dependency_manager_( |
| BrowserContextDependencyManager::GetInstance()), |
| resource_context_(NULL), |
| delegate_(delegate) { |
| Init(); |
| if (delegate_) { |
| base::MessageLoop::current()->PostTask( |
| FROM_HERE, |
| base::Bind(&TestingProfile::FinishInit, base::Unretained(this))); |
| } else { |
| FinishInit(); |
| } |
| } |
| |
| TestingProfile::TestingProfile( |
| const base::FilePath& path, |
| Delegate* delegate, |
| #if defined(ENABLE_EXTENSIONS) |
| scoped_refptr<ExtensionSpecialStoragePolicy> extension_policy, |
| #endif |
| scoped_ptr<PrefServiceSyncable> prefs, |
| TestingProfile* parent, |
| bool guest_session, |
| const std::string& supervised_user_id, |
| scoped_ptr<policy::PolicyService> policy_service, |
| const TestingFactories& factories) |
| : start_time_(Time::Now()), |
| prefs_(prefs.release()), |
| testing_prefs_(NULL), |
| force_incognito_(false), |
| original_profile_(parent), |
| guest_session_(guest_session), |
| supervised_user_id_(supervised_user_id), |
| last_session_exited_cleanly_(true), |
| #if defined(ENABLE_EXTENSIONS) |
| extension_special_storage_policy_(extension_policy), |
| #endif |
| profile_path_(path), |
| browser_context_dependency_manager_( |
| BrowserContextDependencyManager::GetInstance()), |
| resource_context_(NULL), |
| delegate_(delegate), |
| policy_service_(policy_service.release()) { |
| if (parent) |
| parent->SetOffTheRecordProfile(scoped_ptr<Profile>(this)); |
| |
| // If no profile path was supplied, create one. |
| if (profile_path_.empty()) { |
| CreateTempProfileDir(); |
| profile_path_ = temp_dir_.path(); |
| } |
| |
| // Set any testing factories prior to initializing the services. |
| for (TestingFactories::const_iterator it = factories.begin(); |
| it != factories.end(); ++it) { |
| it->first->SetTestingFactory(this, it->second); |
| } |
| |
| Init(); |
| // If caller supplied a delegate, delay the FinishInit invocation until other |
| // tasks have run. |
| // TODO(atwilson): See if this is still required once we convert the current |
| // users of the constructor that takes a Delegate* param. |
| if (delegate_) { |
| base::MessageLoop::current()->PostTask( |
| FROM_HERE, |
| base::Bind(&TestingProfile::FinishInit, base::Unretained(this))); |
| } else { |
| FinishInit(); |
| } |
| } |
| |
| void TestingProfile::CreateTempProfileDir() { |
| if (!temp_dir_.CreateUniqueTempDir()) { |
| LOG(ERROR) << "Failed to create unique temporary directory."; |
| |
| // Fallback logic in case we fail to create unique temporary directory. |
| base::FilePath system_tmp_dir; |
| bool success = PathService::Get(base::DIR_TEMP, &system_tmp_dir); |
| |
| // We're severly screwed if we can't get the system temporary |
| // directory. Die now to avoid writing to the filesystem root |
| // or other bad places. |
| CHECK(success); |
| |
| base::FilePath fallback_dir( |
| system_tmp_dir.AppendASCII("TestingProfilePath")); |
| base::DeleteFile(fallback_dir, true); |
| base::CreateDirectory(fallback_dir); |
| if (!temp_dir_.Set(fallback_dir)) { |
| // That shouldn't happen, but if it does, try to recover. |
| LOG(ERROR) << "Failed to use a fallback temporary directory."; |
| |
| // We're screwed if this fails, see CHECK above. |
| CHECK(temp_dir_.Set(system_tmp_dir)); |
| } |
| } |
| } |
| |
| void TestingProfile::Init() { |
| // If threads have been initialized, we should be on the UI thread. |
| DCHECK(!content::BrowserThread::IsThreadInitialized( |
| content::BrowserThread::UI) || |
| content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
| |
| set_is_guest_profile(guest_session_); |
| |
| #if defined(OS_ANDROID) |
| // Make sure token service knows its running in tests. |
| AndroidProfileOAuth2TokenService::set_is_testing_profile(); |
| #endif |
| |
| // Normally this would happen during browser startup, but for tests |
| // we need to trigger creation of Profile-related services. |
| ChromeBrowserMainExtraPartsProfiles:: |
| EnsureBrowserContextKeyedServiceFactoriesBuilt(); |
| |
| if (prefs_.get()) |
| user_prefs::UserPrefs::Set(this, prefs_.get()); |
| else if (IsOffTheRecord()) |
| CreateIncognitoPrefService(); |
| else |
| CreateTestingPrefService(); |
| |
| if (!base::PathExists(profile_path_)) |
| base::CreateDirectory(profile_path_); |
| |
| // TODO(joaodasilva): remove this once this PKS isn't created in ProfileImpl |
| // anymore, after converting the PrefService to a PKS. Until then it must |
| // be associated with a TestingProfile too. |
| if (!IsOffTheRecord()) |
| CreateProfilePolicyConnector(); |
| |
| #if defined(ENABLE_EXTENSIONS) |
| extensions::ExtensionSystemFactory::GetInstance()->SetTestingFactory( |
| this, extensions::TestExtensionSystem::Build); |
| #endif |
| |
| // Prefs for incognito profiles are set in CreateIncognitoPrefService() by |
| // simulating ProfileImpl::GetOffTheRecordPrefs(). |
| if (!IsOffTheRecord()) { |
| DCHECK(!original_profile_); |
| user_prefs::PrefRegistrySyncable* pref_registry = |
| static_cast<user_prefs::PrefRegistrySyncable*>( |
| prefs_->DeprecatedGetPrefRegistry()); |
| browser_context_dependency_manager_-> |
| RegisterProfilePrefsForServices(this, pref_registry); |
| } |
| |
| browser_context_dependency_manager_->CreateBrowserContextServicesForTest( |
| this); |
| |
| #if defined(ENABLE_NOTIFICATIONS) |
| // Install profile keyed service factory hooks for dummy/test services |
| DesktopNotificationServiceFactory::GetInstance()->SetTestingFactory( |
| this, CreateTestDesktopNotificationService); |
| #endif |
| |
| #if defined(ENABLE_SUPERVISED_USERS) |
| if (!IsOffTheRecord()) { |
| SupervisedUserSettingsService* settings_service = |
| SupervisedUserSettingsServiceFactory::GetForProfile(this); |
| TestingPrefStore* store = new TestingPrefStore(); |
| settings_service->Init(store); |
| store->SetInitializationCompleted(); |
| } |
| #endif |
| |
| profile_name_ = "testing_profile"; |
| } |
| |
| void TestingProfile::FinishInit() { |
| DCHECK(content::NotificationService::current()); |
| content::NotificationService::current()->Notify( |
| chrome::NOTIFICATION_PROFILE_CREATED, |
| content::Source<Profile>(static_cast<Profile*>(this)), |
| content::NotificationService::NoDetails()); |
| |
| ProfileManager* profile_manager = g_browser_process->profile_manager(); |
| if (profile_manager) |
| profile_manager->InitProfileUserPrefs(this); |
| |
| if (delegate_) |
| delegate_->OnProfileCreated(this, true, false); |
| } |
| |
| TestingProfile::~TestingProfile() { |
| // Revert to non-incognito mode before shutdown. |
| force_incognito_ = false; |
| |
| // If this profile owns an incognito profile, tear it down first. |
| incognito_profile_.reset(); |
| |
| // Any objects holding live URLFetchers should be deleted before teardown. |
| TemplateURLFetcherFactory::ShutdownForProfile(this); |
| |
| MaybeSendDestroyedNotification(); |
| |
| // Remember whether a TopSites has been created for the current profile, |
| // so that we can run cleanup after destroying all services. |
| bool had_top_sites = HasTopSites(this); |
| |
| browser_context_dependency_manager_->DestroyBrowserContextServices(this); |
| |
| if (host_content_settings_map_.get()) |
| host_content_settings_map_->ShutdownOnUIThread(); |
| |
| // Wait until TopSites shutdown tasks have completed if a TopSites has |
| // been created for the current profile. |
| if (had_top_sites) |
| CleanupAfterTopSitesDestroyed(); |
| |
| if (pref_proxy_config_tracker_.get()) |
| pref_proxy_config_tracker_->DetachFromPrefService(); |
| // Failing a post == leaks == heapcheck failure. Make that an immediate test |
| // failure. |
| if (resource_context_) { |
| CHECK(BrowserThread::DeleteSoon(BrowserThread::IO, FROM_HERE, |
| resource_context_)); |
| resource_context_ = NULL; |
| content::RunAllPendingInMessageLoop(BrowserThread::IO); |
| } |
| } |
| |
| void TestingProfile::CreateFallbackIconService() { |
| FaviconServiceFactory::GetInstance()->SetTestingFactory( |
| this, BuildFallbackIconService); |
| } |
| |
| void TestingProfile::CreateFaviconService() { |
| // It is up to the caller to create the history service if one is needed. |
| FaviconServiceFactory::GetInstance()->SetTestingFactory( |
| this, BuildFaviconService); |
| } |
| |
| bool TestingProfile::CreateHistoryService(bool delete_file, bool no_db) { |
| DestroyHistoryService(); |
| if (delete_file) { |
| base::FilePath path = GetPath(); |
| path = path.Append(history::kHistoryFilename); |
| if (!base::DeleteFile(path, false) || base::PathExists(path)) |
| return false; |
| } |
| // This will create and init the history service. |
| history::HistoryService* history_service = |
| static_cast<history::HistoryService*>( |
| HistoryServiceFactory::GetInstance()->SetTestingFactoryAndUse( |
| this, BuildHistoryService)); |
| if (!history_service->Init( |
| no_db, GetPrefs()->GetString(prefs::kAcceptLanguages), |
| history::HistoryDatabaseParamsForPath(GetPath()))) { |
| HistoryServiceFactory::GetInstance()->SetTestingFactory(this, nullptr); |
| return false; |
| } |
| // Some tests expect that CreateHistoryService() will also make the |
| // InMemoryURLIndex available. |
| InMemoryURLIndexFactory::GetInstance()->SetTestingFactory( |
| this, BuildInMemoryURLIndex); |
| // Disable WebHistoryService by default, since it makes network requests. |
| WebHistoryServiceFactory::GetInstance()->SetTestingFactory(this, nullptr); |
| return true; |
| } |
| |
| void TestingProfile::DestroyHistoryService() { |
| history::HistoryService* history_service = |
| HistoryServiceFactory::GetForProfileWithoutCreating(this); |
| if (!history_service) |
| return; |
| |
| history_service->ClearCachedDataForContextID(0); |
| history_service->SetOnBackendDestroyTask(base::MessageLoop::QuitClosure()); |
| history_service->Cleanup(); |
| HistoryServiceFactory::ShutdownForProfile(this); |
| |
| // Wait for the backend class to terminate before deleting the files and |
| // moving to the next test. Note: if this never terminates, somebody is |
| // probably leaking a reference to the history backend, so it never calls |
| // our destroy task. |
| base::MessageLoop::current()->Run(); |
| |
| // Make sure we don't have any event pending that could disrupt the next |
| // test. |
| base::MessageLoop::current()->PostTask(FROM_HERE, |
| base::MessageLoop::QuitClosure()); |
| base::MessageLoop::current()->Run(); |
| } |
| |
| void TestingProfile::CreateTopSites() { |
| DestroyTopSites(); |
| TopSitesFactory::GetInstance()->SetTestingFactoryAndUse(this, BuildTopSites); |
| } |
| |
| void TestingProfile::DestroyTopSites() { |
| TopSitesFactory* top_sites_factory = TopSitesFactory::GetInstance(); |
| if (top_sites_factory->GetForProfileIfExists(this)) { |
| // BrowserContextKeyedServiceFactory will destroy the previous service when |
| // registering a new testing factory so use this to ensure that destroy the |
| // old service. |
| top_sites_factory->SetTestingFactory(this, nullptr); |
| CleanupAfterTopSitesDestroyed(); |
| } |
| } |
| |
| void TestingProfile::CreateBookmarkModel(bool delete_file) { |
| if (delete_file) { |
| base::FilePath path = GetPath().Append(bookmarks::kBookmarksFileName); |
| base::DeleteFile(path, false); |
| } |
| ChromeHistoryClientFactory::GetInstance()->SetTestingFactory( |
| this, BuildChromeHistoryClient); |
| ChromeBookmarkClientFactory::GetInstance()->SetTestingFactory( |
| this, BuildChromeBookmarkClient); |
| // This creates the BookmarkModel. |
| ignore_result(BookmarkModelFactory::GetInstance()->SetTestingFactoryAndUse( |
| this, BuildBookmarkModel)); |
| } |
| |
| void TestingProfile::CreateWebDataService() { |
| WebDataServiceFactory::GetInstance()->SetTestingFactory( |
| this, BuildWebDataService); |
| } |
| |
| void TestingProfile::BlockUntilHistoryIndexIsRefreshed() { |
| // Only get the history service if it actually exists since the caller of the |
| // test should explicitly call CreateHistoryService to build it. |
| history::HistoryService* history_service = |
| HistoryServiceFactory::GetForProfileWithoutCreating(this); |
| DCHECK(history_service); |
| InMemoryURLIndex* index = InMemoryURLIndexFactory::GetForProfile(this); |
| if (!index || index->restored()) |
| return; |
| base::RunLoop run_loop; |
| HistoryIndexRestoreObserver observer( |
| content::GetQuitTaskForRunLoop(&run_loop)); |
| index->set_restore_cache_observer(&observer); |
| run_loop.Run(); |
| index->set_restore_cache_observer(NULL); |
| DCHECK(index->restored()); |
| } |
| |
| // TODO(phajdan.jr): Doesn't this hang if Top Sites are already loaded? |
| void TestingProfile::BlockUntilTopSitesLoaded() { |
| scoped_refptr<content::MessageLoopRunner> runner = |
| new content::MessageLoopRunner; |
| WaitTopSitesLoadedObserver observer(runner.get()); |
| scoped_refptr<history::TopSites> top_sites = |
| TopSitesFactory::GetForProfile(this); |
| top_sites->AddObserver(&observer); |
| runner->Run(); |
| top_sites->RemoveObserver(&observer); |
| } |
| |
| void TestingProfile::SetGuestSession(bool guest) { |
| guest_session_ = guest; |
| } |
| |
| base::FilePath TestingProfile::GetPath() const { |
| return profile_path_; |
| } |
| |
| scoped_ptr<content::ZoomLevelDelegate> TestingProfile::CreateZoomLevelDelegate( |
| const base::FilePath& partition_path) { |
| return make_scoped_ptr(new chrome::ChromeZoomLevelPrefs( |
| GetPrefs(), GetPath(), partition_path, |
| ui_zoom::ZoomEventManager::GetForBrowserContext(this)->GetWeakPtr())); |
| } |
| |
| scoped_refptr<base::SequencedTaskRunner> TestingProfile::GetIOTaskRunner() { |
| return base::MessageLoop::current()->message_loop_proxy(); |
| } |
| |
| TestingPrefServiceSyncable* TestingProfile::GetTestingPrefService() { |
| DCHECK(prefs_); |
| DCHECK(testing_prefs_); |
| return testing_prefs_; |
| } |
| |
| TestingProfile* TestingProfile::AsTestingProfile() { |
| return this; |
| } |
| |
| std::string TestingProfile::GetProfileUserName() const { |
| return profile_name_; |
| } |
| |
| Profile::ProfileType TestingProfile::GetProfileType() const { |
| if (guest_session_) |
| return GUEST_PROFILE; |
| if (force_incognito_ || original_profile_) |
| return INCOGNITO_PROFILE; |
| return REGULAR_PROFILE; |
| } |
| |
| bool TestingProfile::IsOffTheRecord() const { |
| return force_incognito_ || original_profile_; |
| } |
| |
| void TestingProfile::SetOffTheRecordProfile(scoped_ptr<Profile> profile) { |
| DCHECK(!IsOffTheRecord()); |
| DCHECK_EQ(this, profile->GetOriginalProfile()); |
| incognito_profile_ = profile.Pass(); |
| } |
| |
| Profile* TestingProfile::GetOffTheRecordProfile() { |
| if (IsOffTheRecord()) |
| return this; |
| if (!incognito_profile_) |
| TestingProfile::Builder().BuildIncognito(this); |
| return incognito_profile_.get(); |
| } |
| |
| bool TestingProfile::HasOffTheRecordProfile() { |
| return incognito_profile_.get() != NULL; |
| } |
| |
| Profile* TestingProfile::GetOriginalProfile() { |
| if (original_profile_) |
| return original_profile_; |
| return this; |
| } |
| |
| bool TestingProfile::IsSupervised() { |
| return !supervised_user_id_.empty(); |
| } |
| |
| bool TestingProfile::IsChild() { |
| #if defined(ENABLE_SUPERVISED_USERS) |
| return supervised_user_id_ == supervised_users::kChildAccountSUID; |
| #else |
| return false; |
| #endif |
| } |
| |
| bool TestingProfile::IsLegacySupervised() { |
| return IsSupervised() && !IsChild(); |
| } |
| |
| #if defined(ENABLE_EXTENSIONS) |
| void TestingProfile::SetExtensionSpecialStoragePolicy( |
| ExtensionSpecialStoragePolicy* extension_special_storage_policy) { |
| extension_special_storage_policy_ = extension_special_storage_policy; |
| } |
| #endif |
| |
| ExtensionSpecialStoragePolicy* |
| TestingProfile::GetExtensionSpecialStoragePolicy() { |
| #if defined(ENABLE_EXTENSIONS) |
| if (!extension_special_storage_policy_.get()) |
| extension_special_storage_policy_ = new ExtensionSpecialStoragePolicy(NULL); |
| return extension_special_storage_policy_.get(); |
| #else |
| return NULL; |
| #endif |
| } |
| |
| net::CookieMonster* TestingProfile::GetCookieMonster() { |
| if (!GetRequestContext()) |
| return NULL; |
| return GetRequestContext()->GetURLRequestContext()->cookie_store()-> |
| GetCookieMonster(); |
| } |
| |
| void TestingProfile::CreateTestingPrefService() { |
| DCHECK(!prefs_.get()); |
| testing_prefs_ = new TestingPrefServiceSyncable(); |
| prefs_.reset(testing_prefs_); |
| user_prefs::UserPrefs::Set(this, prefs_.get()); |
| chrome::RegisterUserProfilePrefs(testing_prefs_->registry()); |
| } |
| |
| void TestingProfile::CreateIncognitoPrefService() { |
| DCHECK(original_profile_); |
| DCHECK(!testing_prefs_); |
| // Simplified version of ProfileImpl::GetOffTheRecordPrefs(). Note this |
| // leaves testing_prefs_ unset. |
| prefs_.reset(original_profile_->prefs_->CreateIncognitoPrefService(NULL)); |
| user_prefs::UserPrefs::Set(this, prefs_.get()); |
| } |
| |
| void TestingProfile::CreateProfilePolicyConnector() { |
| #if defined(ENABLE_CONFIGURATION_POLICY) |
| schema_registry_service_ = |
| policy::SchemaRegistryServiceFactory::CreateForContext( |
| this, policy::Schema(), NULL); |
| CHECK_EQ(schema_registry_service_.get(), |
| policy::SchemaRegistryServiceFactory::GetForContext(this)); |
| #endif // defined(ENABLE_CONFIGURATION_POLICY) |
| |
| if (!policy_service_) { |
| #if defined(ENABLE_CONFIGURATION_POLICY) |
| std::vector<policy::ConfigurationPolicyProvider*> providers; |
| policy_service_.reset(new policy::PolicyServiceImpl(providers)); |
| #else |
| policy_service_.reset(new policy::PolicyServiceStub()); |
| #endif |
| } |
| profile_policy_connector_.reset(new policy::ProfilePolicyConnector()); |
| profile_policy_connector_->InitForTesting(policy_service_.Pass()); |
| policy::ProfilePolicyConnectorFactory::GetInstance()->SetServiceForTesting( |
| this, profile_policy_connector_.get()); |
| CHECK_EQ(profile_policy_connector_.get(), |
| policy::ProfilePolicyConnectorFactory::GetForBrowserContext(this)); |
| } |
| |
| PrefService* TestingProfile::GetPrefs() { |
| DCHECK(prefs_); |
| return prefs_.get(); |
| } |
| |
| const PrefService* TestingProfile::GetPrefs() const { |
| DCHECK(prefs_); |
| return prefs_.get(); |
| } |
| |
| chrome::ChromeZoomLevelPrefs* TestingProfile::GetZoomLevelPrefs() { |
| return static_cast<chrome::ChromeZoomLevelPrefs*>( |
| GetDefaultStoragePartition(this)->GetZoomLevelDelegate()); |
| } |
| |
| DownloadManagerDelegate* TestingProfile::GetDownloadManagerDelegate() { |
| return NULL; |
| } |
| |
| net::URLRequestContextGetter* TestingProfile::GetRequestContext() { |
| return GetDefaultStoragePartition(this)->GetURLRequestContext(); |
| } |
| |
| net::URLRequestContextGetter* TestingProfile::CreateRequestContext( |
| content::ProtocolHandlerMap* protocol_handlers, |
| content::URLRequestInterceptorScopedVector request_interceptors) { |
| return new net::TestURLRequestContextGetter( |
| BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO)); |
| } |
| |
| net::URLRequestContextGetter* TestingProfile::GetRequestContextForRenderProcess( |
| int renderer_child_id) { |
| content::RenderProcessHost* rph = content::RenderProcessHost::FromID( |
| renderer_child_id); |
| return rph->GetStoragePartition()->GetURLRequestContext(); |
| } |
| |
| net::URLRequestContextGetter* TestingProfile::GetMediaRequestContext() { |
| return NULL; |
| } |
| |
| net::URLRequestContextGetter* |
| TestingProfile::GetMediaRequestContextForRenderProcess( |
| int renderer_child_id) { |
| return NULL; |
| } |
| |
| net::URLRequestContextGetter* |
| TestingProfile::GetMediaRequestContextForStoragePartition( |
| const base::FilePath& partition_path, |
| bool in_memory) { |
| return NULL; |
| } |
| |
| net::URLRequestContextGetter* TestingProfile::GetRequestContextForExtensions() { |
| if (!extensions_request_context_.get()) |
| extensions_request_context_ = new TestExtensionURLRequestContextGetter(); |
| return extensions_request_context_.get(); |
| } |
| |
| net::SSLConfigService* TestingProfile::GetSSLConfigService() { |
| if (!GetRequestContext()) |
| return NULL; |
| return GetRequestContext()->GetURLRequestContext()->ssl_config_service(); |
| } |
| |
| net::URLRequestContextGetter* |
| TestingProfile::CreateRequestContextForStoragePartition( |
| const base::FilePath& partition_path, |
| bool in_memory, |
| content::ProtocolHandlerMap* protocol_handlers, |
| content::URLRequestInterceptorScopedVector request_interceptors) { |
| // We don't test storage partitions here yet, so returning the same dummy |
| // context is sufficient for now. |
| return GetRequestContext(); |
| } |
| |
| content::ResourceContext* TestingProfile::GetResourceContext() { |
| if (!resource_context_) |
| resource_context_ = new content::MockResourceContext(); |
| return resource_context_; |
| } |
| |
| HostContentSettingsMap* TestingProfile::GetHostContentSettingsMap() { |
| DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| if (!host_content_settings_map_.get()) { |
| host_content_settings_map_ = new HostContentSettingsMap(GetPrefs(), false); |
| #if defined(ENABLE_EXTENSIONS) |
| ExtensionService* extension_service = |
| extensions::ExtensionSystem::Get(this)->extension_service(); |
| if (extension_service) { |
| extension_service->RegisterContentSettings( |
| host_content_settings_map_.get()); |
| } |
| #endif |
| } |
| return host_content_settings_map_.get(); |
| } |
| |
| content::BrowserPluginGuestManager* TestingProfile::GetGuestManager() { |
| #if defined(ENABLE_EXTENSIONS) |
| return extensions::GuestViewManager::FromBrowserContext(this); |
| #else |
| return NULL; |
| #endif |
| } |
| |
| content::PushMessagingService* TestingProfile::GetPushMessagingService() { |
| return NULL; |
| } |
| |
| bool TestingProfile::IsSameProfile(Profile *p) { |
| return this == p; |
| } |
| |
| base::Time TestingProfile::GetStartTime() const { |
| return start_time_; |
| } |
| |
| base::FilePath TestingProfile::last_selected_directory() { |
| return last_selected_directory_; |
| } |
| |
| void TestingProfile::set_last_selected_directory(const base::FilePath& path) { |
| last_selected_directory_ = path; |
| } |
| |
| PrefProxyConfigTracker* TestingProfile::GetProxyConfigTracker() { |
| if (!pref_proxy_config_tracker_.get()) { |
| // TestingProfile is used in unit tests, where local state is not available. |
| pref_proxy_config_tracker_.reset( |
| ProxyServiceFactory::CreatePrefProxyConfigTrackerOfProfile(GetPrefs(), |
| NULL)); |
| } |
| return pref_proxy_config_tracker_.get(); |
| } |
| |
| void TestingProfile::BlockUntilHistoryProcessesPendingRequests() { |
| history::HistoryService* history_service = |
| HistoryServiceFactory::GetForProfile(this, |
| ServiceAccessType::EXPLICIT_ACCESS); |
| DCHECK(history_service); |
| DCHECK(base::MessageLoop::current()); |
| |
| base::CancelableTaskTracker tracker; |
| history_service->ScheduleDBTask( |
| scoped_ptr<history::HistoryDBTask>( |
| new QuittingHistoryDBTask()), |
| &tracker); |
| base::MessageLoop::current()->Run(); |
| } |
| |
| chrome_browser_net::Predictor* TestingProfile::GetNetworkPredictor() { |
| return NULL; |
| } |
| |
| DevToolsNetworkController* TestingProfile::GetDevToolsNetworkController() { |
| return NULL; |
| } |
| |
| void TestingProfile::ClearNetworkingHistorySince( |
| base::Time time, |
| const base::Closure& completion) { |
| if (!completion.is_null()) { |
| BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, completion); |
| } |
| } |
| |
| GURL TestingProfile::GetHomePage() { |
| return GURL(chrome::kChromeUINewTabURL); |
| } |
| |
| PrefService* TestingProfile::GetOffTheRecordPrefs() { |
| return NULL; |
| } |
| |
| storage::SpecialStoragePolicy* TestingProfile::GetSpecialStoragePolicy() { |
| #if defined(ENABLE_EXTENSIONS) |
| return GetExtensionSpecialStoragePolicy(); |
| #else |
| return NULL; |
| #endif |
| } |
| |
| content::SSLHostStateDelegate* TestingProfile::GetSSLHostStateDelegate() { |
| return NULL; |
| } |
| |
| content::PermissionManager* TestingProfile::GetPermissionManager() { |
| return NULL; |
| } |
| |
| bool TestingProfile::WasCreatedByVersionOrLater(const std::string& version) { |
| return true; |
| } |
| |
| bool TestingProfile::IsGuestSession() const { |
| return guest_session_; |
| } |
| |
| Profile::ExitType TestingProfile::GetLastSessionExitType() { |
| return last_session_exited_cleanly_ ? EXIT_NORMAL : EXIT_CRASHED; |
| } |
| |
| TestingProfile::Builder::Builder() |
| : build_called_(false), |
| delegate_(NULL), |
| guest_session_(false) { |
| } |
| |
| TestingProfile::Builder::~Builder() { |
| } |
| |
| void TestingProfile::Builder::SetPath(const base::FilePath& path) { |
| path_ = path; |
| } |
| |
| void TestingProfile::Builder::SetDelegate(Delegate* delegate) { |
| delegate_ = delegate; |
| } |
| |
| #if defined(ENABLE_EXTENSIONS) |
| void TestingProfile::Builder::SetExtensionSpecialStoragePolicy( |
| scoped_refptr<ExtensionSpecialStoragePolicy> policy) { |
| extension_policy_ = policy; |
| } |
| #endif |
| |
| void TestingProfile::Builder::SetPrefService( |
| scoped_ptr<PrefServiceSyncable> prefs) { |
| pref_service_ = prefs.Pass(); |
| } |
| |
| void TestingProfile::Builder::SetGuestSession() { |
| guest_session_ = true; |
| } |
| |
| void TestingProfile::Builder::SetSupervisedUserId( |
| const std::string& supervised_user_id) { |
| supervised_user_id_ = supervised_user_id; |
| } |
| |
| void TestingProfile::Builder::SetPolicyService( |
| scoped_ptr<policy::PolicyService> policy_service) { |
| policy_service_ = policy_service.Pass(); |
| } |
| |
| void TestingProfile::Builder::AddTestingFactory( |
| BrowserContextKeyedServiceFactory* service_factory, |
| BrowserContextKeyedServiceFactory::TestingFactoryFunction callback) { |
| testing_factories_.push_back(std::make_pair(service_factory, callback)); |
| } |
| |
| scoped_ptr<TestingProfile> TestingProfile::Builder::Build() { |
| DCHECK(!build_called_); |
| build_called_ = true; |
| |
| return scoped_ptr<TestingProfile>(new TestingProfile(path_, |
| delegate_, |
| #if defined(ENABLE_EXTENSIONS) |
| extension_policy_, |
| #endif |
| pref_service_.Pass(), |
| NULL, |
| guest_session_, |
| supervised_user_id_, |
| policy_service_.Pass(), |
| testing_factories_)); |
| } |
| |
| TestingProfile* TestingProfile::Builder::BuildIncognito( |
| TestingProfile* original_profile) { |
| DCHECK(!build_called_); |
| DCHECK(original_profile); |
| build_called_ = true; |
| |
| // Note: Owned by |original_profile|. |
| return new TestingProfile(path_, |
| delegate_, |
| #if defined(ENABLE_EXTENSIONS) |
| extension_policy_, |
| #endif |
| pref_service_.Pass(), |
| original_profile, |
| guest_session_, |
| supervised_user_id_, |
| policy_service_.Pass(), |
| testing_factories_); |
| } |