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