Home | History | Annotate | Download | only in base
      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
      3 // found in the LICENSE file.
      4 
      5 #include "chrome/test/base/testing_profile.h"
      6 
      7 #include "build/build_config.h"
      8 
      9 #include "base/base_paths.h"
     10 #include "base/command_line.h"
     11 #include "base/file_util.h"
     12 #include "base/message_loop/message_loop_proxy.h"
     13 #include "base/path_service.h"
     14 #include "base/prefs/testing_pref_store.h"
     15 #include "base/run_loop.h"
     16 #include "base/strings/string_number_conversions.h"
     17 #include "chrome/browser/autocomplete/autocomplete_classifier.h"
     18 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
     19 #include "chrome/browser/bookmarks/chrome_bookmark_client.h"
     20 #include "chrome/browser/bookmarks/chrome_bookmark_client_factory.h"
     21 #include "chrome/browser/browser_process.h"
     22 #include "chrome/browser/chrome_notification_types.h"
     23 #include "chrome/browser/content_settings/host_content_settings_map.h"
     24 #include "chrome/browser/extensions/extension_service.h"
     25 #include "chrome/browser/extensions/extension_special_storage_policy.h"
     26 #include "chrome/browser/extensions/extension_system_factory.h"
     27 #include "chrome/browser/extensions/test_extension_system.h"
     28 #include "chrome/browser/favicon/favicon_service.h"
     29 #include "chrome/browser/favicon/favicon_service_factory.h"
     30 #include "chrome/browser/history/chrome_history_client.h"
     31 #include "chrome/browser/history/chrome_history_client_factory.h"
     32 #include "chrome/browser/history/history_backend.h"
     33 #include "chrome/browser/history/history_db_task.h"
     34 #include "chrome/browser/history/history_service.h"
     35 #include "chrome/browser/history/history_service_factory.h"
     36 #include "chrome/browser/history/top_sites.h"
     37 #include "chrome/browser/history/web_history_service_factory.h"
     38 #include "chrome/browser/net/pref_proxy_config_tracker.h"
     39 #include "chrome/browser/net/proxy_service_factory.h"
     40 #include "chrome/browser/notifications/desktop_notification_service.h"
     41 #include "chrome/browser/notifications/desktop_notification_service_factory.h"
     42 #include "chrome/browser/policy/profile_policy_connector.h"
     43 #include "chrome/browser/policy/profile_policy_connector_factory.h"
     44 #include "chrome/browser/prefs/browser_prefs.h"
     45 #include "chrome/browser/prefs/pref_service_syncable.h"
     46 #include "chrome/browser/prerender/prerender_manager.h"
     47 #include "chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.h"
     48 #include "chrome/browser/profiles/profile_manager.h"
     49 #include "chrome/browser/profiles/storage_partition_descriptor.h"
     50 #include "chrome/browser/search_engines/template_url_fetcher_factory.h"
     51 #include "chrome/browser/webdata/web_data_service.h"
     52 #include "chrome/browser/webdata/web_data_service_factory.h"
     53 #include "chrome/common/chrome_constants.h"
     54 #include "chrome/common/chrome_switches.h"
     55 #include "chrome/common/pref_names.h"
     56 #include "chrome/common/url_constants.h"
     57 #include "chrome/test/base/history_index_restore_observer.h"
     58 #include "chrome/test/base/testing_pref_service_syncable.h"
     59 #include "chrome/test/base/ui_test_utils.h"
     60 #include "components/bookmarks/browser/bookmark_model.h"
     61 #include "components/bookmarks/common/bookmark_constants.h"
     62 #include "components/keyed_service/content/browser_context_dependency_manager.h"
     63 #include "components/policy/core/common/policy_service.h"
     64 #include "components/user_prefs/user_prefs.h"
     65 #include "content/public/browser/browser_thread.h"
     66 #include "content/public/browser/cookie_store_factory.h"
     67 #include "content/public/browser/notification_service.h"
     68 #include "content/public/browser/render_process_host.h"
     69 #include "content/public/browser/storage_partition.h"
     70 #include "content/public/test/mock_resource_context.h"
     71 #include "content/public/test/test_utils.h"
     72 #include "extensions/browser/extension_system.h"
     73 #include "extensions/common/constants.h"
     74 #include "net/cookies/cookie_monster.h"
     75 #include "net/url_request/url_request_context.h"
     76 #include "net/url_request/url_request_context_getter.h"
     77 #include "net/url_request/url_request_test_util.h"
     78 #include "testing/gmock/include/gmock/gmock.h"
     79 
     80 #if defined(ENABLE_CONFIGURATION_POLICY)
     81 #include "chrome/browser/policy/schema_registry_service.h"
     82 #include "chrome/browser/policy/schema_registry_service_factory.h"
     83 #include "components/policy/core/common/configuration_policy_provider.h"
     84 #include "components/policy/core/common/policy_service_impl.h"
     85 #include "components/policy/core/common/schema.h"
     86 #else
     87 #include "components/policy/core/common/policy_service_stub.h"
     88 #endif  // defined(ENABLE_CONFIGURATION_POLICY)
     89 
     90 #if defined(ENABLE_EXTENSIONS)
     91 #include "chrome/browser/guest_view/guest_view_manager.h"
     92 #endif
     93 
     94 #if defined(OS_ANDROID)
     95 #include "chrome/browser/signin/android_profile_oauth2_token_service.h"
     96 #endif
     97 
     98 #if defined(ENABLE_MANAGED_USERS)
     99 #include "chrome/browser/supervised_user/supervised_user_settings_service.h"
    100 #include "chrome/browser/supervised_user/supervised_user_settings_service_factory.h"
    101 #endif
    102 
    103 using base::Time;
    104 using content::BrowserThread;
    105 using content::DownloadManagerDelegate;
    106 using testing::NiceMock;
    107 using testing::Return;
    108 
    109 namespace {
    110 
    111 // Task used to make sure history has finished processing a request. Intended
    112 // for use with BlockUntilHistoryProcessesPendingRequests.
    113 
    114 class QuittingHistoryDBTask : public history::HistoryDBTask {
    115  public:
    116   QuittingHistoryDBTask() {}
    117 
    118   virtual bool RunOnDBThread(history::HistoryBackend* backend,
    119                              history::HistoryDatabase* db) OVERRIDE {
    120     return true;
    121   }
    122 
    123   virtual void DoneRunOnMainThread() OVERRIDE {
    124     base::MessageLoop::current()->Quit();
    125   }
    126 
    127  private:
    128   virtual ~QuittingHistoryDBTask() {}
    129 
    130   DISALLOW_COPY_AND_ASSIGN(QuittingHistoryDBTask);
    131 };
    132 
    133 class TestExtensionURLRequestContext : public net::URLRequestContext {
    134  public:
    135   TestExtensionURLRequestContext() {
    136     net::CookieMonster* cookie_monster =
    137         content::CreateCookieStore(content::CookieStoreConfig())->
    138             GetCookieMonster();
    139     const char* schemes[] = {extensions::kExtensionScheme};
    140     cookie_monster->SetCookieableSchemes(schemes, 1);
    141     set_cookie_store(cookie_monster);
    142   }
    143 
    144   virtual ~TestExtensionURLRequestContext() {}
    145 };
    146 
    147 class TestExtensionURLRequestContextGetter
    148     : public net::URLRequestContextGetter {
    149  public:
    150   virtual net::URLRequestContext* GetURLRequestContext() OVERRIDE {
    151     if (!context_.get())
    152       context_.reset(new TestExtensionURLRequestContext());
    153     return context_.get();
    154   }
    155   virtual scoped_refptr<base::SingleThreadTaskRunner>
    156       GetNetworkTaskRunner() const OVERRIDE {
    157     return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO);
    158   }
    159 
    160  protected:
    161   virtual ~TestExtensionURLRequestContextGetter() {}
    162 
    163  private:
    164   scoped_ptr<net::URLRequestContext> context_;
    165 };
    166 
    167 #if defined(ENABLE_NOTIFICATIONS)
    168 KeyedService* CreateTestDesktopNotificationService(
    169     content::BrowserContext* profile) {
    170   return new DesktopNotificationService(static_cast<Profile*>(profile), NULL);
    171 }
    172 #endif
    173 
    174 }  // namespace
    175 
    176 // static
    177 #if defined(OS_CHROMEOS)
    178 // Must be kept in sync with
    179 // ChromeBrowserMainPartsChromeos::PreEarlyInitialization.
    180 const char TestingProfile::kTestUserProfileDir[] = "test-user";
    181 #else
    182 const char TestingProfile::kTestUserProfileDir[] = "Default";
    183 #endif
    184 
    185 TestingProfile::TestingProfile()
    186     : start_time_(Time::Now()),
    187       testing_prefs_(NULL),
    188       incognito_(false),
    189       force_incognito_(false),
    190       original_profile_(NULL),
    191       guest_session_(false),
    192       last_session_exited_cleanly_(true),
    193       browser_context_dependency_manager_(
    194           BrowserContextDependencyManager::GetInstance()),
    195       resource_context_(NULL),
    196       delegate_(NULL) {
    197   CreateTempProfileDir();
    198   profile_path_ = temp_dir_.path();
    199 
    200   Init();
    201   FinishInit();
    202 }
    203 
    204 TestingProfile::TestingProfile(const base::FilePath& path)
    205     : start_time_(Time::Now()),
    206       testing_prefs_(NULL),
    207       incognito_(false),
    208       force_incognito_(false),
    209       original_profile_(NULL),
    210       guest_session_(false),
    211       last_session_exited_cleanly_(true),
    212       profile_path_(path),
    213       browser_context_dependency_manager_(
    214           BrowserContextDependencyManager::GetInstance()),
    215       resource_context_(NULL),
    216       delegate_(NULL) {
    217   Init();
    218   FinishInit();
    219 }
    220 
    221 TestingProfile::TestingProfile(const base::FilePath& path,
    222                                Delegate* delegate)
    223     : start_time_(Time::Now()),
    224       testing_prefs_(NULL),
    225       incognito_(false),
    226       force_incognito_(false),
    227       original_profile_(NULL),
    228       guest_session_(false),
    229       last_session_exited_cleanly_(true),
    230       profile_path_(path),
    231       browser_context_dependency_manager_(
    232           BrowserContextDependencyManager::GetInstance()),
    233       resource_context_(NULL),
    234       delegate_(delegate) {
    235   Init();
    236   if (delegate_) {
    237     base::MessageLoop::current()->PostTask(
    238         FROM_HERE,
    239         base::Bind(&TestingProfile::FinishInit, base::Unretained(this)));
    240   } else {
    241     FinishInit();
    242   }
    243 }
    244 
    245 TestingProfile::TestingProfile(
    246     const base::FilePath& path,
    247     Delegate* delegate,
    248     scoped_refptr<ExtensionSpecialStoragePolicy> extension_policy,
    249     scoped_ptr<PrefServiceSyncable> prefs,
    250     bool incognito,
    251     bool guest_session,
    252     const std::string& supervised_user_id,
    253     scoped_ptr<policy::PolicyService> policy_service,
    254     const TestingFactories& factories)
    255     : start_time_(Time::Now()),
    256       prefs_(prefs.release()),
    257       testing_prefs_(NULL),
    258       incognito_(incognito),
    259       force_incognito_(false),
    260       original_profile_(NULL),
    261       guest_session_(guest_session),
    262       supervised_user_id_(supervised_user_id),
    263       last_session_exited_cleanly_(true),
    264       extension_special_storage_policy_(extension_policy),
    265       profile_path_(path),
    266       browser_context_dependency_manager_(
    267           BrowserContextDependencyManager::GetInstance()),
    268       resource_context_(NULL),
    269       delegate_(delegate),
    270       policy_service_(policy_service.release()) {
    271   // If no profile path was supplied, create one.
    272   if (profile_path_.empty()) {
    273     CreateTempProfileDir();
    274     profile_path_ = temp_dir_.path();
    275   }
    276 
    277   // Set any testing factories prior to initializing the services.
    278   for (TestingFactories::const_iterator it = factories.begin();
    279        it != factories.end(); ++it) {
    280     it->first->SetTestingFactory(this, it->second);
    281   }
    282 
    283   Init();
    284   // If caller supplied a delegate, delay the FinishInit invocation until other
    285   // tasks have run.
    286   // TODO(atwilson): See if this is still required once we convert the current
    287   // users of the constructor that takes a Delegate* param.
    288   if (delegate_) {
    289     base::MessageLoop::current()->PostTask(
    290         FROM_HERE,
    291         base::Bind(&TestingProfile::FinishInit, base::Unretained(this)));
    292   } else {
    293     FinishInit();
    294   }
    295 }
    296 
    297 void TestingProfile::CreateTempProfileDir() {
    298   if (!temp_dir_.CreateUniqueTempDir()) {
    299     LOG(ERROR) << "Failed to create unique temporary directory.";
    300 
    301     // Fallback logic in case we fail to create unique temporary directory.
    302     base::FilePath system_tmp_dir;
    303     bool success = PathService::Get(base::DIR_TEMP, &system_tmp_dir);
    304 
    305     // We're severly screwed if we can't get the system temporary
    306     // directory. Die now to avoid writing to the filesystem root
    307     // or other bad places.
    308     CHECK(success);
    309 
    310     base::FilePath fallback_dir(
    311         system_tmp_dir.AppendASCII("TestingProfilePath"));
    312     base::DeleteFile(fallback_dir, true);
    313     base::CreateDirectory(fallback_dir);
    314     if (!temp_dir_.Set(fallback_dir)) {
    315       // That shouldn't happen, but if it does, try to recover.
    316       LOG(ERROR) << "Failed to use a fallback temporary directory.";
    317 
    318       // We're screwed if this fails, see CHECK above.
    319       CHECK(temp_dir_.Set(system_tmp_dir));
    320     }
    321   }
    322 }
    323 
    324 void TestingProfile::Init() {
    325   // If threads have been initialized, we should be on the UI thread.
    326   DCHECK(!content::BrowserThread::IsThreadInitialized(
    327              content::BrowserThread::UI) ||
    328          content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
    329 
    330 #if defined(OS_ANDROID)
    331   // Make sure token service knows its running in tests.
    332   AndroidProfileOAuth2TokenService::set_is_testing_profile();
    333 #endif
    334 
    335   // Normally this would happen during browser startup, but for tests
    336   // we need to trigger creation of Profile-related services.
    337   ChromeBrowserMainExtraPartsProfiles::
    338       EnsureBrowserContextKeyedServiceFactoriesBuilt();
    339 
    340   if (prefs_.get())
    341     user_prefs::UserPrefs::Set(this, prefs_.get());
    342   else
    343     CreateTestingPrefService();
    344 
    345   if (!base::PathExists(profile_path_))
    346     base::CreateDirectory(profile_path_);
    347 
    348   // TODO(joaodasilva): remove this once this PKS isn't created in ProfileImpl
    349   // anymore, after converting the PrefService to a PKS. Until then it must
    350   // be associated with a TestingProfile too.
    351   if (!IsOffTheRecord())
    352     CreateProfilePolicyConnector();
    353 
    354   extensions::ExtensionSystemFactory::GetInstance()->SetTestingFactory(
    355       this, extensions::TestExtensionSystem::Build);
    356 
    357   // If no original profile was specified for this profile: register preferences
    358   // even if this is an incognito profile - this allows tests to create a
    359   // standalone incognito profile while still having prefs registered.
    360   if (!IsOffTheRecord() || !original_profile_) {
    361     user_prefs::PrefRegistrySyncable* pref_registry =
    362         static_cast<user_prefs::PrefRegistrySyncable*>(
    363             prefs_->DeprecatedGetPrefRegistry());
    364     browser_context_dependency_manager_->
    365         RegisterProfilePrefsForServices(this, pref_registry);
    366   }
    367 
    368   browser_context_dependency_manager_->CreateBrowserContextServicesForTest(
    369       this);
    370 
    371 #if defined(ENABLE_NOTIFICATIONS)
    372   // Install profile keyed service factory hooks for dummy/test services
    373   DesktopNotificationServiceFactory::GetInstance()->SetTestingFactory(
    374       this, CreateTestDesktopNotificationService);
    375 #endif
    376 
    377 #if defined(ENABLE_MANAGED_USERS)
    378   SupervisedUserSettingsService* settings_service =
    379       SupervisedUserSettingsServiceFactory::GetForProfile(this);
    380   TestingPrefStore* store = new TestingPrefStore();
    381   settings_service->Init(store);
    382   store->SetInitializationCompleted();
    383 #endif
    384 
    385   profile_name_ = "testing_profile";
    386 }
    387 
    388 void TestingProfile::FinishInit() {
    389   DCHECK(content::NotificationService::current());
    390   content::NotificationService::current()->Notify(
    391       chrome::NOTIFICATION_PROFILE_CREATED,
    392       content::Source<Profile>(static_cast<Profile*>(this)),
    393       content::NotificationService::NoDetails());
    394 
    395   ProfileManager* profile_manager = g_browser_process->profile_manager();
    396   if (profile_manager)
    397     profile_manager->InitProfileUserPrefs(this);
    398 
    399   if (delegate_)
    400     delegate_->OnProfileCreated(this, true, false);
    401 }
    402 
    403 TestingProfile::~TestingProfile() {
    404   // Revert to non-incognito mode before shutdown.
    405   force_incognito_ = false;
    406 
    407   // Any objects holding live URLFetchers should be deleted before teardown.
    408   TemplateURLFetcherFactory::ShutdownForProfile(this);
    409 
    410   MaybeSendDestroyedNotification();
    411 
    412   browser_context_dependency_manager_->DestroyBrowserContextServices(this);
    413 
    414   if (host_content_settings_map_.get())
    415     host_content_settings_map_->ShutdownOnUIThread();
    416 
    417   DestroyTopSites();
    418 
    419   if (pref_proxy_config_tracker_.get())
    420     pref_proxy_config_tracker_->DetachFromPrefService();
    421   // Failing a post == leaks == heapcheck failure. Make that an immediate test
    422   // failure.
    423   if (resource_context_) {
    424     CHECK(BrowserThread::DeleteSoon(BrowserThread::IO, FROM_HERE,
    425                                     resource_context_));
    426     resource_context_ = NULL;
    427     content::RunAllPendingInMessageLoop(BrowserThread::IO);
    428   }
    429 }
    430 
    431 static KeyedService* BuildFaviconService(content::BrowserContext* profile) {
    432   return new FaviconService(static_cast<Profile*>(profile));
    433 }
    434 
    435 void TestingProfile::CreateFaviconService() {
    436   // It is up to the caller to create the history service if one is needed.
    437   FaviconServiceFactory::GetInstance()->SetTestingFactory(
    438       this, BuildFaviconService);
    439 }
    440 
    441 static KeyedService* BuildHistoryService(content::BrowserContext* context) {
    442   Profile* profile = static_cast<Profile*>(context);
    443   return new HistoryService(ChromeHistoryClientFactory::GetForProfile(profile),
    444                             profile);
    445 }
    446 
    447 bool TestingProfile::CreateHistoryService(bool delete_file, bool no_db) {
    448   DestroyHistoryService();
    449   if (delete_file) {
    450     base::FilePath path = GetPath();
    451     path = path.Append(chrome::kHistoryFilename);
    452     if (!base::DeleteFile(path, false) || base::PathExists(path))
    453       return false;
    454   }
    455   // This will create and init the history service.
    456   HistoryService* history_service = static_cast<HistoryService*>(
    457       HistoryServiceFactory::GetInstance()->SetTestingFactoryAndUse(
    458           this, BuildHistoryService));
    459   if (!history_service->Init(this->GetPath(), no_db)) {
    460     HistoryServiceFactory::GetInstance()->SetTestingFactoryAndUse(this, NULL);
    461   }
    462   // Disable WebHistoryService by default, since it makes network requests.
    463   WebHistoryServiceFactory::GetInstance()->SetTestingFactory(this, NULL);
    464   return true;
    465 }
    466 
    467 void TestingProfile::DestroyHistoryService() {
    468   HistoryService* history_service =
    469       HistoryServiceFactory::GetForProfileWithoutCreating(this);
    470   if (!history_service)
    471     return;
    472 
    473   history_service->ClearCachedDataForContextID(0);
    474   history_service->SetOnBackendDestroyTask(base::MessageLoop::QuitClosure());
    475   history_service->Cleanup();
    476   HistoryServiceFactory::ShutdownForProfile(this);
    477 
    478   // Wait for the backend class to terminate before deleting the files and
    479   // moving to the next test. Note: if this never terminates, somebody is
    480   // probably leaking a reference to the history backend, so it never calls
    481   // our destroy task.
    482   base::MessageLoop::current()->Run();
    483 
    484   // Make sure we don't have any event pending that could disrupt the next
    485   // test.
    486   base::MessageLoop::current()->PostTask(FROM_HERE,
    487                                          base::MessageLoop::QuitClosure());
    488   base::MessageLoop::current()->Run();
    489 }
    490 
    491 void TestingProfile::CreateTopSites() {
    492   DestroyTopSites();
    493   top_sites_ = history::TopSites::Create(
    494       this, GetPath().Append(chrome::kTopSitesFilename));
    495 }
    496 
    497 void TestingProfile::DestroyTopSites() {
    498   if (top_sites_.get()) {
    499     top_sites_->Shutdown();
    500     top_sites_ = NULL;
    501     // TopSitesImpl::Shutdown schedules some tasks (from TopSitesBackend) that
    502     // need to be run to properly shutdown. Run all pending tasks now. This is
    503     // normally handled by browser_process shutdown.
    504     if (base::MessageLoop::current())
    505       base::MessageLoop::current()->RunUntilIdle();
    506   }
    507 }
    508 
    509 static KeyedService* BuildBookmarkModel(content::BrowserContext* context) {
    510   Profile* profile = static_cast<Profile*>(context);
    511   ChromeBookmarkClient* bookmark_client =
    512       ChromeBookmarkClientFactory::GetForProfile(profile);
    513   BookmarkModel* bookmark_model = new BookmarkModel(bookmark_client, false);
    514   bookmark_client->Init(bookmark_model);
    515   bookmark_model->Load(profile->GetPrefs(),
    516                        profile->GetPrefs()->GetString(prefs::kAcceptLanguages),
    517                        profile->GetPath(),
    518                        profile->GetIOTaskRunner(),
    519                        content::BrowserThread::GetMessageLoopProxyForThread(
    520                            content::BrowserThread::UI));
    521   return bookmark_model;
    522 }
    523 
    524 static KeyedService* BuildChromeBookmarkClient(
    525     content::BrowserContext* context) {
    526   return new ChromeBookmarkClient(static_cast<Profile*>(context));
    527 }
    528 
    529 static KeyedService* BuildChromeHistoryClient(
    530     content::BrowserContext* context) {
    531   Profile* profile = static_cast<Profile*>(context);
    532   return new ChromeHistoryClient(BookmarkModelFactory::GetForProfile(profile));
    533 }
    534 
    535 void TestingProfile::CreateBookmarkModel(bool delete_file) {
    536   if (delete_file) {
    537     base::FilePath path = GetPath().Append(bookmarks::kBookmarksFileName);
    538     base::DeleteFile(path, false);
    539   }
    540   ChromeHistoryClientFactory::GetInstance()->SetTestingFactory(
    541       this, BuildChromeHistoryClient);
    542   ChromeBookmarkClientFactory::GetInstance()->SetTestingFactory(
    543       this, BuildChromeBookmarkClient);
    544   // This creates the BookmarkModel.
    545   ignore_result(BookmarkModelFactory::GetInstance()->SetTestingFactoryAndUse(
    546       this, BuildBookmarkModel));
    547 }
    548 
    549 static KeyedService* BuildWebDataService(content::BrowserContext* profile) {
    550   return new WebDataServiceWrapper(static_cast<Profile*>(profile));
    551 }
    552 
    553 void TestingProfile::CreateWebDataService() {
    554   WebDataServiceFactory::GetInstance()->SetTestingFactory(
    555       this, BuildWebDataService);
    556 }
    557 
    558 void TestingProfile::BlockUntilHistoryIndexIsRefreshed() {
    559   // Only get the history service if it actually exists since the caller of the
    560   // test should explicitly call CreateHistoryService to build it.
    561   HistoryService* history_service =
    562       HistoryServiceFactory::GetForProfileWithoutCreating(this);
    563   DCHECK(history_service);
    564   history::InMemoryURLIndex* index = history_service->InMemoryIndex();
    565   if (!index || index->restored())
    566     return;
    567   base::RunLoop run_loop;
    568   HistoryIndexRestoreObserver observer(
    569       content::GetQuitTaskForRunLoop(&run_loop));
    570   index->set_restore_cache_observer(&observer);
    571   run_loop.Run();
    572   index->set_restore_cache_observer(NULL);
    573   DCHECK(index->restored());
    574 }
    575 
    576 // TODO(phajdan.jr): Doesn't this hang if Top Sites are already loaded?
    577 void TestingProfile::BlockUntilTopSitesLoaded() {
    578   content::WindowedNotificationObserver top_sites_loaded_observer(
    579       chrome::NOTIFICATION_TOP_SITES_LOADED,
    580       content::NotificationService::AllSources());
    581   top_sites_loaded_observer.Wait();
    582 }
    583 
    584 void TestingProfile::SetGuestSession(bool guest) {
    585   guest_session_ = guest;
    586 }
    587 
    588 base::FilePath TestingProfile::GetPath() const {
    589   return profile_path_;
    590 }
    591 
    592 scoped_refptr<base::SequencedTaskRunner> TestingProfile::GetIOTaskRunner() {
    593   return base::MessageLoop::current()->message_loop_proxy();
    594 }
    595 
    596 TestingPrefServiceSyncable* TestingProfile::GetTestingPrefService() {
    597   if (!prefs_.get())
    598     CreateTestingPrefService();
    599   DCHECK(testing_prefs_);
    600   return testing_prefs_;
    601 }
    602 
    603 TestingProfile* TestingProfile::AsTestingProfile() {
    604   return this;
    605 }
    606 
    607 std::string TestingProfile::GetProfileName() {
    608   return profile_name_;
    609 }
    610 
    611 Profile::ProfileType TestingProfile::GetProfileType() const {
    612   if (guest_session_)
    613     return GUEST_PROFILE;
    614   if (force_incognito_ || incognito_)
    615     return INCOGNITO_PROFILE;
    616   return REGULAR_PROFILE;
    617 }
    618 
    619 bool TestingProfile::IsOffTheRecord() const {
    620   return force_incognito_ || incognito_;
    621 }
    622 
    623 void TestingProfile::SetOffTheRecordProfile(scoped_ptr<Profile> profile) {
    624   DCHECK(!IsOffTheRecord());
    625   incognito_profile_ = profile.Pass();
    626 }
    627 
    628 void TestingProfile::SetOriginalProfile(Profile* profile) {
    629   DCHECK(IsOffTheRecord());
    630   original_profile_ = profile;
    631 }
    632 
    633 Profile* TestingProfile::GetOffTheRecordProfile() {
    634   if (IsOffTheRecord())
    635     return this;
    636   if (!incognito_profile_) {
    637     TestingProfile::Builder builder;
    638     builder.SetIncognito();
    639     scoped_ptr<TestingProfile> incognito_test_profile(builder.Build());
    640     incognito_test_profile->SetOriginalProfile(this);
    641     SetOffTheRecordProfile(incognito_test_profile.PassAs<Profile>());
    642   }
    643   return incognito_profile_.get();
    644 }
    645 
    646 bool TestingProfile::HasOffTheRecordProfile() {
    647   return incognito_profile_.get() != NULL;
    648 }
    649 
    650 Profile* TestingProfile::GetOriginalProfile() {
    651   if (original_profile_)
    652     return original_profile_;
    653   return this;
    654 }
    655 
    656 bool TestingProfile::IsSupervised() {
    657   return !supervised_user_id_.empty();
    658 }
    659 
    660 ExtensionService* TestingProfile::GetExtensionService() {
    661   return extensions::ExtensionSystem::Get(this)->extension_service();
    662 }
    663 
    664 void TestingProfile::SetExtensionSpecialStoragePolicy(
    665     ExtensionSpecialStoragePolicy* extension_special_storage_policy) {
    666   extension_special_storage_policy_ = extension_special_storage_policy;
    667 }
    668 
    669 ExtensionSpecialStoragePolicy*
    670 TestingProfile::GetExtensionSpecialStoragePolicy() {
    671   if (!extension_special_storage_policy_.get())
    672     extension_special_storage_policy_ = new ExtensionSpecialStoragePolicy(NULL);
    673   return extension_special_storage_policy_.get();
    674 }
    675 
    676 net::CookieMonster* TestingProfile::GetCookieMonster() {
    677   if (!GetRequestContext())
    678     return NULL;
    679   return GetRequestContext()->GetURLRequestContext()->cookie_store()->
    680       GetCookieMonster();
    681 }
    682 
    683 void TestingProfile::CreateTestingPrefService() {
    684   DCHECK(!prefs_.get());
    685   testing_prefs_ = new TestingPrefServiceSyncable();
    686   prefs_.reset(testing_prefs_);
    687   user_prefs::UserPrefs::Set(this, prefs_.get());
    688   chrome::RegisterUserProfilePrefs(testing_prefs_->registry());
    689 }
    690 
    691 void TestingProfile::CreateProfilePolicyConnector() {
    692 #if defined(ENABLE_CONFIGURATION_POLICY)
    693   schema_registry_service_ =
    694       policy::SchemaRegistryServiceFactory::CreateForContext(
    695           this, policy::Schema(), NULL);
    696   CHECK_EQ(schema_registry_service_.get(),
    697            policy::SchemaRegistryServiceFactory::GetForContext(this));
    698 #endif  // defined(ENABLE_CONFIGURATION_POLICY)
    699 
    700 if (!policy_service_) {
    701 #if defined(ENABLE_CONFIGURATION_POLICY)
    702     std::vector<policy::ConfigurationPolicyProvider*> providers;
    703     policy_service_.reset(new policy::PolicyServiceImpl(providers));
    704 #else
    705     policy_service_.reset(new policy::PolicyServiceStub());
    706 #endif
    707   }
    708   profile_policy_connector_.reset(new policy::ProfilePolicyConnector());
    709   profile_policy_connector_->InitForTesting(policy_service_.Pass());
    710   policy::ProfilePolicyConnectorFactory::GetInstance()->SetServiceForTesting(
    711       this, profile_policy_connector_.get());
    712   CHECK_EQ(profile_policy_connector_.get(),
    713            policy::ProfilePolicyConnectorFactory::GetForProfile(this));
    714 }
    715 
    716 PrefService* TestingProfile::GetPrefs() {
    717   if (!prefs_.get()) {
    718     CreateTestingPrefService();
    719   }
    720   return prefs_.get();
    721 }
    722 
    723 history::TopSites* TestingProfile::GetTopSites() {
    724   return top_sites_.get();
    725 }
    726 
    727 history::TopSites* TestingProfile::GetTopSitesWithoutCreating() {
    728   return top_sites_.get();
    729 }
    730 
    731 DownloadManagerDelegate* TestingProfile::GetDownloadManagerDelegate() {
    732   return NULL;
    733 }
    734 
    735 net::URLRequestContextGetter* TestingProfile::GetRequestContext() {
    736   return GetDefaultStoragePartition(this)->GetURLRequestContext();
    737 }
    738 
    739 net::URLRequestContextGetter* TestingProfile::CreateRequestContext(
    740     content::ProtocolHandlerMap* protocol_handlers,
    741     content::URLRequestInterceptorScopedVector request_interceptors) {
    742   return new net::TestURLRequestContextGetter(
    743             BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO));
    744 }
    745 
    746 net::URLRequestContextGetter* TestingProfile::GetRequestContextForRenderProcess(
    747     int renderer_child_id) {
    748   content::RenderProcessHost* rph = content::RenderProcessHost::FromID(
    749       renderer_child_id);
    750   return rph->GetStoragePartition()->GetURLRequestContext();
    751 }
    752 
    753 net::URLRequestContextGetter* TestingProfile::GetMediaRequestContext() {
    754   return NULL;
    755 }
    756 
    757 net::URLRequestContextGetter*
    758 TestingProfile::GetMediaRequestContextForRenderProcess(
    759     int renderer_child_id) {
    760   return NULL;
    761 }
    762 
    763 net::URLRequestContextGetter*
    764 TestingProfile::GetMediaRequestContextForStoragePartition(
    765     const base::FilePath& partition_path,
    766     bool in_memory) {
    767   return NULL;
    768 }
    769 
    770 net::URLRequestContextGetter* TestingProfile::GetRequestContextForExtensions() {
    771   if (!extensions_request_context_.get())
    772     extensions_request_context_ = new TestExtensionURLRequestContextGetter();
    773   return extensions_request_context_.get();
    774 }
    775 
    776 net::SSLConfigService* TestingProfile::GetSSLConfigService() {
    777   if (!GetRequestContext())
    778     return NULL;
    779   return GetRequestContext()->GetURLRequestContext()->ssl_config_service();
    780 }
    781 
    782 net::URLRequestContextGetter*
    783 TestingProfile::CreateRequestContextForStoragePartition(
    784     const base::FilePath& partition_path,
    785     bool in_memory,
    786     content::ProtocolHandlerMap* protocol_handlers,
    787     content::URLRequestInterceptorScopedVector request_interceptors) {
    788   // We don't test storage partitions here yet, so returning the same dummy
    789   // context is sufficient for now.
    790   return GetRequestContext();
    791 }
    792 
    793 content::ResourceContext* TestingProfile::GetResourceContext() {
    794   if (!resource_context_)
    795     resource_context_ = new content::MockResourceContext();
    796   return resource_context_;
    797 }
    798 
    799 HostContentSettingsMap* TestingProfile::GetHostContentSettingsMap() {
    800   if (!host_content_settings_map_.get()) {
    801     host_content_settings_map_ = new HostContentSettingsMap(GetPrefs(), false);
    802 #if defined(ENABLE_EXTENSIONS)
    803     ExtensionService* extension_service = GetExtensionService();
    804     if (extension_service)
    805       host_content_settings_map_->RegisterExtensionService(extension_service);
    806 #endif
    807   }
    808   return host_content_settings_map_.get();
    809 }
    810 
    811 content::BrowserPluginGuestManager* TestingProfile::GetGuestManager() {
    812 #if defined(ENABLE_EXTENSIONS)
    813   return GuestViewManager::FromBrowserContext(this);
    814 #else
    815   return NULL;
    816 #endif
    817 }
    818 
    819 content::PushMessagingService* TestingProfile::GetPushMessagingService() {
    820   return NULL;
    821 }
    822 
    823 bool TestingProfile::IsSameProfile(Profile *p) {
    824   return this == p;
    825 }
    826 
    827 base::Time TestingProfile::GetStartTime() const {
    828   return start_time_;
    829 }
    830 
    831 base::FilePath TestingProfile::last_selected_directory() {
    832   return last_selected_directory_;
    833 }
    834 
    835 void TestingProfile::set_last_selected_directory(const base::FilePath& path) {
    836   last_selected_directory_ = path;
    837 }
    838 
    839 PrefProxyConfigTracker* TestingProfile::GetProxyConfigTracker() {
    840   if (!pref_proxy_config_tracker_.get()) {
    841     // TestingProfile is used in unit tests, where local state is not available.
    842     pref_proxy_config_tracker_.reset(
    843         ProxyServiceFactory::CreatePrefProxyConfigTrackerOfProfile(GetPrefs(),
    844                                                                    NULL));
    845   }
    846   return pref_proxy_config_tracker_.get();
    847 }
    848 
    849 void TestingProfile::BlockUntilHistoryProcessesPendingRequests() {
    850   HistoryService* history_service =
    851       HistoryServiceFactory::GetForProfile(this, Profile::EXPLICIT_ACCESS);
    852   DCHECK(history_service);
    853   DCHECK(base::MessageLoop::current());
    854 
    855   CancelableRequestConsumer consumer;
    856   history_service->ScheduleDBTask(new QuittingHistoryDBTask(), &consumer);
    857   base::MessageLoop::current()->Run();
    858 }
    859 
    860 chrome_browser_net::Predictor* TestingProfile::GetNetworkPredictor() {
    861   return NULL;
    862 }
    863 
    864 DevToolsNetworkController* TestingProfile::GetDevToolsNetworkController() {
    865   return NULL;
    866 }
    867 
    868 void TestingProfile::ClearNetworkingHistorySince(
    869     base::Time time,
    870     const base::Closure& completion) {
    871   if (!completion.is_null()) {
    872     BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, completion);
    873   }
    874 }
    875 
    876 void TestingProfile::ClearDomainReliabilityMonitor(
    877     domain_reliability::DomainReliabilityClearMode mode,
    878     const base::Closure& completion) {
    879   if (!completion.is_null()) {
    880     BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, completion);
    881   }
    882 }
    883 
    884 GURL TestingProfile::GetHomePage() {
    885   return GURL(chrome::kChromeUINewTabURL);
    886 }
    887 
    888 PrefService* TestingProfile::GetOffTheRecordPrefs() {
    889   return NULL;
    890 }
    891 
    892 quota::SpecialStoragePolicy* TestingProfile::GetSpecialStoragePolicy() {
    893   return GetExtensionSpecialStoragePolicy();
    894 }
    895 
    896 bool TestingProfile::WasCreatedByVersionOrLater(const std::string& version) {
    897   return true;
    898 }
    899 
    900 bool TestingProfile::IsGuestSession() const {
    901   return guest_session_;
    902 }
    903 
    904 Profile::ExitType TestingProfile::GetLastSessionExitType() {
    905   return last_session_exited_cleanly_ ? EXIT_NORMAL : EXIT_CRASHED;
    906 }
    907 
    908 TestingProfile::Builder::Builder()
    909     : build_called_(false),
    910       delegate_(NULL),
    911       incognito_(false),
    912       guest_session_(false) {
    913 }
    914 
    915 TestingProfile::Builder::~Builder() {
    916 }
    917 
    918 void TestingProfile::Builder::SetPath(const base::FilePath& path) {
    919   path_ = path;
    920 }
    921 
    922 void TestingProfile::Builder::SetDelegate(Delegate* delegate) {
    923   delegate_ = delegate;
    924 }
    925 
    926 void TestingProfile::Builder::SetExtensionSpecialStoragePolicy(
    927     scoped_refptr<ExtensionSpecialStoragePolicy> policy) {
    928   extension_policy_ = policy;
    929 }
    930 
    931 void TestingProfile::Builder::SetPrefService(
    932     scoped_ptr<PrefServiceSyncable> prefs) {
    933   pref_service_ = prefs.Pass();
    934 }
    935 
    936 void TestingProfile::Builder::SetIncognito() {
    937   incognito_ = true;
    938 }
    939 
    940 void TestingProfile::Builder::SetGuestSession() {
    941   guest_session_ = true;
    942 }
    943 
    944 void TestingProfile::Builder::SetSupervisedUserId(
    945     const std::string& supervised_user_id) {
    946   supervised_user_id_ = supervised_user_id;
    947 }
    948 
    949 void TestingProfile::Builder::SetPolicyService(
    950     scoped_ptr<policy::PolicyService> policy_service) {
    951   policy_service_ = policy_service.Pass();
    952 }
    953 
    954 void TestingProfile::Builder::AddTestingFactory(
    955     BrowserContextKeyedServiceFactory* service_factory,
    956     BrowserContextKeyedServiceFactory::TestingFactoryFunction callback) {
    957   testing_factories_.push_back(std::make_pair(service_factory, callback));
    958 }
    959 
    960 scoped_ptr<TestingProfile> TestingProfile::Builder::Build() {
    961   DCHECK(!build_called_);
    962   build_called_ = true;
    963 
    964   return scoped_ptr<TestingProfile>(new TestingProfile(
    965       path_,
    966       delegate_,
    967       extension_policy_,
    968       pref_service_.Pass(),
    969       incognito_,
    970       guest_session_,
    971       supervised_user_id_,
    972       policy_service_.Pass(),
    973       testing_factories_));
    974 }
    975