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