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