testing_profile.cc revision a02191e04bc25c4935f804f2c080ae28663d096d
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_factory.h"
26#include "chrome/browser/extensions/test_extension_system.h"
27#include "chrome/browser/favicon/favicon_service.h"
28#include "chrome/browser/favicon/favicon_service_factory.h"
29#include "chrome/browser/geolocation/chrome_geolocation_permission_context.h"
30#include "chrome/browser/geolocation/chrome_geolocation_permission_context_factory.h"
31#include "chrome/browser/history/history_backend.h"
32#include "chrome/browser/history/history_db_task.h"
33#include "chrome/browser/history/history_service.h"
34#include "chrome/browser/history/history_service_factory.h"
35#include "chrome/browser/history/top_sites.h"
36#include "chrome/browser/history/web_history_service_factory.h"
37#include "chrome/browser/net/pref_proxy_config_tracker.h"
38#include "chrome/browser/net/proxy_service_factory.h"
39#include "chrome/browser/notifications/desktop_notification_service.h"
40#include "chrome/browser/notifications/desktop_notification_service_factory.h"
41#include "chrome/browser/policy/profile_policy_connector.h"
42#include "chrome/browser/policy/profile_policy_connector_factory.h"
43#include "chrome/browser/prefs/browser_prefs.h"
44#include "chrome/browser/prefs/pref_service_syncable.h"
45#include "chrome/browser/prerender/prerender_manager.h"
46#include "chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.h"
47#include "chrome/browser/profiles/profile_manager.h"
48#include "chrome/browser/profiles/storage_partition_descriptor.h"
49#include "chrome/browser/search_engines/template_url_fetcher_factory.h"
50#include "chrome/browser/webdata/web_data_service.h"
51#include "chrome/browser/webdata/web_data_service_factory.h"
52#include "chrome/common/chrome_constants.h"
53#include "chrome/common/chrome_switches.h"
54#include "chrome/common/pref_names.h"
55#include "chrome/common/url_constants.h"
56#include "chrome/test/base/history_index_restore_observer.h"
57#include "chrome/test/base/testing_pref_service_syncable.h"
58#include "chrome/test/base/ui_test_utils.h"
59#include "components/bookmarks/core/common/bookmark_constants.h"
60#include "components/keyed_service/content/browser_context_dependency_manager.h"
61#include "components/policy/core/common/policy_service.h"
62#include "components/user_prefs/user_prefs.h"
63#include "content/public/browser/browser_thread.h"
64#include "content/public/browser/cookie_store_factory.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/browser/extension_system.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 =
127        content::CreateCookieStore(content::CookieStoreConfig())->
128            GetCookieMonster();
129    const char* schemes[] = {extensions::kExtensionScheme};
130    cookie_monster->SetCookieableSchemes(schemes, 1);
131    set_cookie_store(cookie_monster);
132  }
133
134  virtual ~TestExtensionURLRequestContext() {}
135};
136
137class TestExtensionURLRequestContextGetter
138    : public net::URLRequestContextGetter {
139 public:
140  virtual net::URLRequestContext* GetURLRequestContext() OVERRIDE {
141    if (!context_.get())
142      context_.reset(new TestExtensionURLRequestContext());
143    return context_.get();
144  }
145  virtual scoped_refptr<base::SingleThreadTaskRunner>
146      GetNetworkTaskRunner() const OVERRIDE {
147    return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO);
148  }
149
150 protected:
151  virtual ~TestExtensionURLRequestContextGetter() {}
152
153 private:
154  scoped_ptr<net::URLRequestContext> context_;
155};
156
157#if defined(ENABLE_NOTIFICATIONS)
158KeyedService* CreateTestDesktopNotificationService(
159    content::BrowserContext* profile) {
160  return new DesktopNotificationService(static_cast<Profile*>(profile), NULL);
161}
162#endif
163
164}  // namespace
165
166// static
167#if defined(OS_CHROMEOS)
168// Must be kept in sync with
169// ChromeBrowserMainPartsChromeos::PreEarlyInitialization.
170const char TestingProfile::kTestUserProfileDir[] = "test-user";
171#else
172const char TestingProfile::kTestUserProfileDir[] = "Default";
173#endif
174
175TestingProfile::TestingProfile()
176    : start_time_(Time::Now()),
177      testing_prefs_(NULL),
178      incognito_(false),
179      force_incognito_(false),
180      original_profile_(NULL),
181      guest_session_(false),
182      last_session_exited_cleanly_(true),
183      browser_context_dependency_manager_(
184          BrowserContextDependencyManager::GetInstance()),
185      resource_context_(NULL),
186      delegate_(NULL) {
187  CreateTempProfileDir();
188  profile_path_ = temp_dir_.path();
189
190  Init();
191  FinishInit();
192}
193
194TestingProfile::TestingProfile(const base::FilePath& path)
195    : start_time_(Time::Now()),
196      testing_prefs_(NULL),
197      incognito_(false),
198      force_incognito_(false),
199      original_profile_(NULL),
200      guest_session_(false),
201      last_session_exited_cleanly_(true),
202      profile_path_(path),
203      browser_context_dependency_manager_(
204          BrowserContextDependencyManager::GetInstance()),
205      resource_context_(NULL),
206      delegate_(NULL) {
207  Init();
208  FinishInit();
209}
210
211TestingProfile::TestingProfile(const base::FilePath& path,
212                               Delegate* delegate)
213    : start_time_(Time::Now()),
214      testing_prefs_(NULL),
215      incognito_(false),
216      force_incognito_(false),
217      original_profile_(NULL),
218      guest_session_(false),
219      last_session_exited_cleanly_(true),
220      profile_path_(path),
221      browser_context_dependency_manager_(
222          BrowserContextDependencyManager::GetInstance()),
223      resource_context_(NULL),
224      delegate_(delegate) {
225  Init();
226  if (delegate_) {
227    base::MessageLoop::current()->PostTask(
228        FROM_HERE,
229        base::Bind(&TestingProfile::FinishInit, base::Unretained(this)));
230  } else {
231    FinishInit();
232  }
233}
234
235TestingProfile::TestingProfile(
236    const base::FilePath& path,
237    Delegate* delegate,
238    scoped_refptr<ExtensionSpecialStoragePolicy> extension_policy,
239    scoped_ptr<PrefServiceSyncable> prefs,
240    bool incognito,
241    bool guest_session,
242    const std::string& managed_user_id,
243    scoped_ptr<policy::PolicyService> policy_service,
244    const TestingFactories& factories)
245    : start_time_(Time::Now()),
246      prefs_(prefs.release()),
247      testing_prefs_(NULL),
248      incognito_(incognito),
249      force_incognito_(false),
250      original_profile_(NULL),
251      guest_session_(guest_session),
252      managed_user_id_(managed_user_id),
253      last_session_exited_cleanly_(true),
254      extension_special_storage_policy_(extension_policy),
255      profile_path_(path),
256      browser_context_dependency_manager_(
257          BrowserContextDependencyManager::GetInstance()),
258      resource_context_(NULL),
259      delegate_(delegate),
260      policy_service_(policy_service.release()) {
261
262  // If no profile path was supplied, create one.
263  if (profile_path_.empty()) {
264    CreateTempProfileDir();
265    profile_path_ = temp_dir_.path();
266  }
267
268  // Set any testing factories prior to initializing the services.
269  for (TestingFactories::const_iterator it = factories.begin();
270       it != factories.end(); ++it) {
271    it->first->SetTestingFactory(this, it->second);
272  }
273
274  Init();
275  // If caller supplied a delegate, delay the FinishInit invocation until other
276  // tasks have run.
277  // TODO(atwilson): See if this is still required once we convert the current
278  // users of the constructor that takes a Delegate* param.
279  if (delegate_) {
280    base::MessageLoop::current()->PostTask(
281        FROM_HERE,
282        base::Bind(&TestingProfile::FinishInit, base::Unretained(this)));
283  } else {
284    FinishInit();
285  }
286}
287
288void TestingProfile::CreateTempProfileDir() {
289  if (!temp_dir_.CreateUniqueTempDir()) {
290    LOG(ERROR) << "Failed to create unique temporary directory.";
291
292    // Fallback logic in case we fail to create unique temporary directory.
293    base::FilePath system_tmp_dir;
294    bool success = PathService::Get(base::DIR_TEMP, &system_tmp_dir);
295
296    // We're severly screwed if we can't get the system temporary
297    // directory. Die now to avoid writing to the filesystem root
298    // or other bad places.
299    CHECK(success);
300
301    base::FilePath fallback_dir(
302        system_tmp_dir.AppendASCII("TestingProfilePath"));
303    base::DeleteFile(fallback_dir, true);
304    base::CreateDirectory(fallback_dir);
305    if (!temp_dir_.Set(fallback_dir)) {
306      // That shouldn't happen, but if it does, try to recover.
307      LOG(ERROR) << "Failed to use a fallback temporary directory.";
308
309      // We're screwed if this fails, see CHECK above.
310      CHECK(temp_dir_.Set(system_tmp_dir));
311    }
312  }
313}
314
315void TestingProfile::Init() {
316  // If threads have been initialized, we should be on the UI thread.
317  DCHECK(!content::BrowserThread::IsThreadInitialized(
318             content::BrowserThread::UI) ||
319         content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
320
321  // Normally this would happen during browser startup, but for tests
322  // we need to trigger creation of Profile-related services.
323  ChromeBrowserMainExtraPartsProfiles::
324      EnsureBrowserContextKeyedServiceFactoriesBuilt();
325
326  if (prefs_.get())
327    user_prefs::UserPrefs::Set(this, prefs_.get());
328  else
329    CreateTestingPrefService();
330
331  if (!base::PathExists(profile_path_))
332    base::CreateDirectory(profile_path_);
333
334  // TODO(joaodasilva): remove this once this PKS isn't created in ProfileImpl
335  // anymore, after converting the PrefService to a PKS. Until then it must
336  // be associated with a TestingProfile too.
337  if (!IsOffTheRecord())
338    CreateProfilePolicyConnector();
339
340  extensions::ExtensionSystemFactory::GetInstance()->SetTestingFactory(
341      this, extensions::TestExtensionSystem::Build);
342
343  // If no original profile was specified for this profile: register preferences
344  // even if this is an incognito profile - this allows tests to create a
345  // standalone incognito profile while still having prefs registered.
346  if (!IsOffTheRecord() || !original_profile_) {
347    user_prefs::PrefRegistrySyncable* pref_registry =
348        static_cast<user_prefs::PrefRegistrySyncable*>(
349            prefs_->DeprecatedGetPrefRegistry());
350    browser_context_dependency_manager_->
351        RegisterProfilePrefsForServices(this, pref_registry);
352  }
353
354  browser_context_dependency_manager_->CreateBrowserContextServicesForTest(
355      this);
356
357#if defined(ENABLE_NOTIFICATIONS)
358  // Install profile keyed service factory hooks for dummy/test services
359  DesktopNotificationServiceFactory::GetInstance()->SetTestingFactory(
360      this, CreateTestDesktopNotificationService);
361#endif
362
363#if defined(ENABLE_MANAGED_USERS)
364  ManagedUserSettingsService* settings_service =
365      ManagedUserSettingsServiceFactory::GetForProfile(this);
366  TestingPrefStore* store = new TestingPrefStore();
367  settings_service->Init(store);
368  store->SetInitializationCompleted();
369#endif
370
371  profile_name_ = "testing_profile";
372}
373
374void TestingProfile::FinishInit() {
375  DCHECK(content::NotificationService::current());
376  content::NotificationService::current()->Notify(
377      chrome::NOTIFICATION_PROFILE_CREATED,
378      content::Source<Profile>(static_cast<Profile*>(this)),
379      content::NotificationService::NoDetails());
380
381  ProfileManager* profile_manager = g_browser_process->profile_manager();
382  if (profile_manager)
383    profile_manager->InitProfileUserPrefs(this);
384
385  if (delegate_)
386    delegate_->OnProfileCreated(this, true, false);
387}
388
389TestingProfile::~TestingProfile() {
390  // Revert to non-incognito mode before shutdown.
391  force_incognito_ = false;
392
393  // Any objects holding live URLFetchers should be deleted before teardown.
394  TemplateURLFetcherFactory::ShutdownForProfile(this);
395
396  MaybeSendDestroyedNotification();
397
398  browser_context_dependency_manager_->DestroyBrowserContextServices(this);
399
400  if (host_content_settings_map_.get())
401    host_content_settings_map_->ShutdownOnUIThread();
402
403  DestroyTopSites();
404
405  if (pref_proxy_config_tracker_.get())
406    pref_proxy_config_tracker_->DetachFromPrefService();
407  // Failing a post == leaks == heapcheck failure. Make that an immediate test
408  // failure.
409  if (resource_context_) {
410    CHECK(BrowserThread::DeleteSoon(BrowserThread::IO, FROM_HERE,
411                                    resource_context_));
412    resource_context_ = NULL;
413    content::RunAllPendingInMessageLoop(BrowserThread::IO);
414  }
415}
416
417static KeyedService* BuildFaviconService(content::BrowserContext* profile) {
418  return new FaviconService(static_cast<Profile*>(profile));
419}
420
421void TestingProfile::CreateFaviconService() {
422  // It is up to the caller to create the history service if one is needed.
423  FaviconServiceFactory::GetInstance()->SetTestingFactory(
424      this, BuildFaviconService);
425}
426
427static KeyedService* BuildHistoryService(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 KeyedService* BuildBookmarkModel(content::BrowserContext* context) {
496  Profile* profile = static_cast<Profile*>(context);
497  BookmarkModel* bookmark_model = new BookmarkModel(profile);
498  bookmark_model->Load(profile->GetIOTaskRunner());
499  return bookmark_model;
500}
501
502void TestingProfile::CreateBookmarkModel(bool delete_file) {
503  if (delete_file) {
504    base::FilePath path = GetPath().Append(bookmarks::kBookmarksFileName);
505    base::DeleteFile(path, false);
506  }
507  // This will create a bookmark model.
508  BookmarkModel* bookmark_service = static_cast<BookmarkModel*>(
509      BookmarkModelFactory::GetInstance()->SetTestingFactoryAndUse(
510          this, BuildBookmarkModel));
511
512  HistoryService* history_service =
513      HistoryServiceFactory::GetForProfileWithoutCreating(this);
514  if (history_service) {
515    history_service->history_backend_->bookmark_service_ = bookmark_service;
516    history_service->history_backend_->expirer_.bookmark_service_ =
517        bookmark_service;
518  }
519}
520
521static KeyedService* BuildWebDataService(content::BrowserContext* profile) {
522  return new WebDataServiceWrapper(static_cast<Profile*>(profile));
523}
524
525void TestingProfile::CreateWebDataService() {
526  WebDataServiceFactory::GetInstance()->SetTestingFactory(
527      this, BuildWebDataService);
528}
529
530void TestingProfile::BlockUntilHistoryIndexIsRefreshed() {
531  // Only get the history service if it actually exists since the caller of the
532  // test should explicitly call CreateHistoryService to build it.
533  HistoryService* history_service =
534      HistoryServiceFactory::GetForProfileWithoutCreating(this);
535  DCHECK(history_service);
536  history::InMemoryURLIndex* index = history_service->InMemoryIndex();
537  if (!index || index->restored())
538    return;
539  base::RunLoop run_loop;
540  HistoryIndexRestoreObserver observer(
541      content::GetQuitTaskForRunLoop(&run_loop));
542  index->set_restore_cache_observer(&observer);
543  run_loop.Run();
544  index->set_restore_cache_observer(NULL);
545  DCHECK(index->restored());
546}
547
548// TODO(phajdan.jr): Doesn't this hang if Top Sites are already loaded?
549void TestingProfile::BlockUntilTopSitesLoaded() {
550  content::WindowedNotificationObserver top_sites_loaded_observer(
551      chrome::NOTIFICATION_TOP_SITES_LOADED,
552      content::NotificationService::AllSources());
553  top_sites_loaded_observer.Wait();
554}
555
556base::FilePath TestingProfile::GetPath() const {
557  return profile_path_;
558}
559
560scoped_refptr<base::SequencedTaskRunner> TestingProfile::GetIOTaskRunner() {
561  return base::MessageLoop::current()->message_loop_proxy();
562}
563
564TestingPrefServiceSyncable* TestingProfile::GetTestingPrefService() {
565  if (!prefs_.get())
566    CreateTestingPrefService();
567  DCHECK(testing_prefs_);
568  return testing_prefs_;
569}
570
571TestingProfile* TestingProfile::AsTestingProfile() {
572  return this;
573}
574
575std::string TestingProfile::GetProfileName() {
576  return profile_name_;
577}
578
579Profile::ProfileType TestingProfile::GetProfileType() const {
580  if (guest_session_)
581    return GUEST_PROFILE;
582  if (force_incognito_ || incognito_)
583    return INCOGNITO_PROFILE;
584  return REGULAR_PROFILE;
585}
586
587bool TestingProfile::IsOffTheRecord() const {
588  return force_incognito_ || incognito_;
589}
590
591void TestingProfile::SetOffTheRecordProfile(scoped_ptr<Profile> profile) {
592  DCHECK(!IsOffTheRecord());
593  incognito_profile_ = profile.Pass();
594}
595
596void TestingProfile::SetOriginalProfile(Profile* profile) {
597  DCHECK(IsOffTheRecord());
598  original_profile_ = profile;
599}
600
601Profile* TestingProfile::GetOffTheRecordProfile() {
602  if (IsOffTheRecord())
603    return this;
604  if (!incognito_profile_) {
605    TestingProfile::Builder builder;
606    builder.SetIncognito();
607    scoped_ptr<TestingProfile> incognito_test_profile(builder.Build());
608    incognito_test_profile->SetOriginalProfile(this);
609    SetOffTheRecordProfile(incognito_test_profile.PassAs<Profile>());
610  }
611  return incognito_profile_.get();
612}
613
614bool TestingProfile::HasOffTheRecordProfile() {
615  return incognito_profile_.get() != NULL;
616}
617
618Profile* TestingProfile::GetOriginalProfile() {
619  if (original_profile_)
620    return original_profile_;
621  return this;
622}
623
624bool TestingProfile::IsManaged() {
625  return !managed_user_id_.empty();
626}
627
628ExtensionService* TestingProfile::GetExtensionService() {
629  return extensions::ExtensionSystem::Get(this)->extension_service();
630}
631
632void TestingProfile::SetExtensionSpecialStoragePolicy(
633    ExtensionSpecialStoragePolicy* extension_special_storage_policy) {
634  extension_special_storage_policy_ = extension_special_storage_policy;
635}
636
637ExtensionSpecialStoragePolicy*
638TestingProfile::GetExtensionSpecialStoragePolicy() {
639  if (!extension_special_storage_policy_.get())
640    extension_special_storage_policy_ = new ExtensionSpecialStoragePolicy(NULL);
641  return extension_special_storage_policy_.get();
642}
643
644net::CookieMonster* TestingProfile::GetCookieMonster() {
645  if (!GetRequestContext())
646    return NULL;
647  return GetRequestContext()->GetURLRequestContext()->cookie_store()->
648      GetCookieMonster();
649}
650
651void TestingProfile::CreateTestingPrefService() {
652  DCHECK(!prefs_.get());
653  testing_prefs_ = new TestingPrefServiceSyncable();
654  prefs_.reset(testing_prefs_);
655  user_prefs::UserPrefs::Set(this, prefs_.get());
656  chrome::RegisterUserProfilePrefs(testing_prefs_->registry());
657}
658
659void TestingProfile::CreateProfilePolicyConnector() {
660#if defined(ENABLE_CONFIGURATION_POLICY)
661  schema_registry_service_ =
662      policy::SchemaRegistryServiceFactory::CreateForContext(
663          this, policy::Schema(), NULL);
664  CHECK_EQ(schema_registry_service_.get(),
665           policy::SchemaRegistryServiceFactory::GetForContext(this));
666#endif  // defined(ENABLE_CONFIGURATION_POLICY)
667
668if (!policy_service_) {
669#if defined(ENABLE_CONFIGURATION_POLICY)
670    std::vector<policy::ConfigurationPolicyProvider*> providers;
671    policy_service_.reset(new policy::PolicyServiceImpl(providers));
672#else
673    policy_service_.reset(new policy::PolicyServiceStub());
674#endif
675  }
676  profile_policy_connector_.reset(new policy::ProfilePolicyConnector());
677  profile_policy_connector_->InitForTesting(policy_service_.Pass());
678  policy::ProfilePolicyConnectorFactory::GetInstance()->SetServiceForTesting(
679      this, profile_policy_connector_.get());
680  CHECK_EQ(profile_policy_connector_.get(),
681           policy::ProfilePolicyConnectorFactory::GetForProfile(this));
682}
683
684PrefService* TestingProfile::GetPrefs() {
685  if (!prefs_.get()) {
686    CreateTestingPrefService();
687  }
688  return prefs_.get();
689}
690
691history::TopSites* TestingProfile::GetTopSites() {
692  return top_sites_.get();
693}
694
695history::TopSites* TestingProfile::GetTopSitesWithoutCreating() {
696  return top_sites_.get();
697}
698
699DownloadManagerDelegate* TestingProfile::GetDownloadManagerDelegate() {
700  return NULL;
701}
702
703net::URLRequestContextGetter* TestingProfile::GetRequestContext() {
704  return GetDefaultStoragePartition(this)->GetURLRequestContext();
705}
706
707net::URLRequestContextGetter* TestingProfile::CreateRequestContext(
708    content::ProtocolHandlerMap* protocol_handlers,
709    content::ProtocolHandlerScopedVector protocol_interceptors) {
710  return new net::TestURLRequestContextGetter(
711            BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO));
712}
713
714net::URLRequestContextGetter* TestingProfile::GetRequestContextForRenderProcess(
715    int renderer_child_id) {
716  content::RenderProcessHost* rph = content::RenderProcessHost::FromID(
717      renderer_child_id);
718  return rph->GetStoragePartition()->GetURLRequestContext();
719}
720
721net::URLRequestContextGetter* TestingProfile::GetMediaRequestContext() {
722  return NULL;
723}
724
725net::URLRequestContextGetter*
726TestingProfile::GetMediaRequestContextForRenderProcess(
727    int renderer_child_id) {
728  return NULL;
729}
730
731net::URLRequestContextGetter*
732TestingProfile::GetMediaRequestContextForStoragePartition(
733    const base::FilePath& partition_path,
734    bool in_memory) {
735  return NULL;
736}
737
738void TestingProfile::RequestMidiSysExPermission(
739      int render_process_id,
740      int render_view_id,
741      int bridge_id,
742      const GURL& requesting_frame,
743      bool user_gesture,
744      const MidiSysExPermissionCallback& callback) {
745  // Always reject requests for testing.
746  callback.Run(false);
747}
748
749void TestingProfile::CancelMidiSysExPermissionRequest(
750    int render_process_id,
751    int render_view_id,
752    int bridge_id,
753    const GURL& requesting_frame) {
754}
755
756void TestingProfile::RequestProtectedMediaIdentifierPermission(
757    int render_process_id,
758    int render_view_id,
759    int bridge_id,
760    int group_id,
761    const GURL& requesting_frame,
762    const ProtectedMediaIdentifierPermissionCallback& callback) {
763  // Always reject requests for testing.
764  callback.Run(false);
765}
766
767void TestingProfile::CancelProtectedMediaIdentifierPermissionRequests(
768    int group_id) {
769}
770
771net::URLRequestContextGetter* TestingProfile::GetRequestContextForExtensions() {
772  if (!extensions_request_context_.get())
773    extensions_request_context_ = new TestExtensionURLRequestContextGetter();
774  return extensions_request_context_.get();
775}
776
777net::SSLConfigService* TestingProfile::GetSSLConfigService() {
778  if (!GetRequestContext())
779    return NULL;
780  return GetRequestContext()->GetURLRequestContext()->ssl_config_service();
781}
782
783net::URLRequestContextGetter*
784TestingProfile::CreateRequestContextForStoragePartition(
785    const base::FilePath& partition_path,
786    bool in_memory,
787    content::ProtocolHandlerMap* protocol_handlers,
788    content::ProtocolHandlerScopedVector protocol_interceptors) {
789  // We don't test storage partitions here yet, so returning the same dummy
790  // context is sufficient for now.
791  return GetRequestContext();
792}
793
794content::ResourceContext* TestingProfile::GetResourceContext() {
795  if (!resource_context_)
796    resource_context_ = new content::MockResourceContext();
797  return resource_context_;
798}
799
800HostContentSettingsMap* TestingProfile::GetHostContentSettingsMap() {
801  if (!host_content_settings_map_.get()) {
802    host_content_settings_map_ = new HostContentSettingsMap(GetPrefs(), false);
803#if defined(ENABLE_EXTENSIONS)
804    ExtensionService* extension_service = GetExtensionService();
805    if (extension_service)
806      host_content_settings_map_->RegisterExtensionService(extension_service);
807#endif
808  }
809  return host_content_settings_map_.get();
810}
811
812content::GeolocationPermissionContext*
813TestingProfile::GetGeolocationPermissionContext() {
814  return ChromeGeolocationPermissionContextFactory::GetForProfile(this);
815}
816
817std::wstring TestingProfile::GetName() {
818  return std::wstring();
819}
820
821std::wstring TestingProfile::GetID() {
822  return id_;
823}
824
825void TestingProfile::SetID(const std::wstring& id) {
826  id_ = id;
827}
828
829bool TestingProfile::IsSameProfile(Profile *p) {
830  return this == p;
831}
832
833base::Time TestingProfile::GetStartTime() const {
834  return start_time_;
835}
836
837base::FilePath TestingProfile::last_selected_directory() {
838  return last_selected_directory_;
839}
840
841void TestingProfile::set_last_selected_directory(const base::FilePath& path) {
842  last_selected_directory_ = path;
843}
844
845PrefProxyConfigTracker* TestingProfile::GetProxyConfigTracker() {
846  if (!pref_proxy_config_tracker_.get()) {
847    // TestingProfile is used in unit tests, where local state is not available.
848    pref_proxy_config_tracker_.reset(
849        ProxyServiceFactory::CreatePrefProxyConfigTrackerOfProfile(GetPrefs(),
850                                                                   NULL));
851  }
852  return pref_proxy_config_tracker_.get();
853}
854
855void TestingProfile::BlockUntilHistoryProcessesPendingRequests() {
856  HistoryService* history_service =
857      HistoryServiceFactory::GetForProfile(this, Profile::EXPLICIT_ACCESS);
858  DCHECK(history_service);
859  DCHECK(base::MessageLoop::current());
860
861  CancelableRequestConsumer consumer;
862  history_service->ScheduleDBTask(new QuittingHistoryDBTask(), &consumer);
863  base::MessageLoop::current()->Run();
864}
865
866chrome_browser_net::Predictor* TestingProfile::GetNetworkPredictor() {
867  return NULL;
868}
869
870void TestingProfile::ClearNetworkingHistorySince(
871    base::Time time,
872    const base::Closure& completion) {
873  if (!completion.is_null()) {
874    BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, completion);
875  }
876}
877
878GURL TestingProfile::GetHomePage() {
879  return GURL(chrome::kChromeUINewTabURL);
880}
881
882PrefService* TestingProfile::GetOffTheRecordPrefs() {
883  return NULL;
884}
885
886quota::SpecialStoragePolicy* TestingProfile::GetSpecialStoragePolicy() {
887  return GetExtensionSpecialStoragePolicy();
888}
889
890bool TestingProfile::WasCreatedByVersionOrLater(const std::string& version) {
891  return true;
892}
893
894bool TestingProfile::IsGuestSession() const {
895  return guest_session_;
896}
897
898Profile::ExitType TestingProfile::GetLastSessionExitType() {
899  return last_session_exited_cleanly_ ? EXIT_NORMAL : EXIT_CRASHED;
900}
901
902TestingProfile::Builder::Builder()
903    : build_called_(false),
904      delegate_(NULL),
905      incognito_(false),
906      guest_session_(false) {
907}
908
909TestingProfile::Builder::~Builder() {
910}
911
912void TestingProfile::Builder::SetPath(const base::FilePath& path) {
913  path_ = path;
914}
915
916void TestingProfile::Builder::SetDelegate(Delegate* delegate) {
917  delegate_ = delegate;
918}
919
920void TestingProfile::Builder::SetExtensionSpecialStoragePolicy(
921    scoped_refptr<ExtensionSpecialStoragePolicy> policy) {
922  extension_policy_ = policy;
923}
924
925void TestingProfile::Builder::SetPrefService(
926    scoped_ptr<PrefServiceSyncable> prefs) {
927  pref_service_ = prefs.Pass();
928}
929
930void TestingProfile::Builder::SetIncognito() {
931  incognito_ = true;
932}
933
934void TestingProfile::Builder::SetGuestSession() {
935  guest_session_ = true;
936}
937
938void TestingProfile::Builder::SetManagedUserId(
939    const std::string& managed_user_id) {
940  managed_user_id_ = managed_user_id;
941}
942
943void TestingProfile::Builder::SetPolicyService(
944    scoped_ptr<policy::PolicyService> policy_service) {
945  policy_service_ = policy_service.Pass();
946}
947
948void TestingProfile::Builder::AddTestingFactory(
949    BrowserContextKeyedServiceFactory* service_factory,
950    BrowserContextKeyedServiceFactory::TestingFactoryFunction callback) {
951  testing_factories_.push_back(std::make_pair(service_factory, callback));
952}
953
954scoped_ptr<TestingProfile> TestingProfile::Builder::Build() {
955  DCHECK(!build_called_);
956  build_called_ = true;
957
958  return scoped_ptr<TestingProfile>(new TestingProfile(
959      path_,
960      delegate_,
961      extension_policy_,
962      pref_service_.Pass(),
963      incognito_,
964      guest_session_,
965      managed_user_id_,
966      policy_service_.Pass(),
967      testing_factories_));
968}
969