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