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