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