summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorerg@chromium.org <erg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-07-22 08:17:08 +0000
committererg@chromium.org <erg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-07-22 08:17:08 +0000
commit50cd994072d4156e2fb1fafa948e58baf49b6f75 (patch)
tree2e81a07124173dd46f503e0d2d93bf7030909e6f
parent3240c4c924ad029cf1b06a74531cdfaa53d58718 (diff)
downloadchromium_src-50cd994072d4156e2fb1fafa948e58baf49b6f75.zip
chromium_src-50cd994072d4156e2fb1fafa948e58baf49b6f75.tar.gz
chromium_src-50cd994072d4156e2fb1fafa948e58baf49b6f75.tar.bz2
Profiles: There should be an equivalent profile creation message to the ProfileDependencyManager for non-lazy initialization of services that need to be started with the profile.
BUG=77155 TEST=none Review URL: http://codereview.chromium.org/7285014 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@93574 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/background/background_contents_service_factory.cc8
-rw-r--r--chrome/browser/background/background_contents_service_factory.h2
-rw-r--r--chrome/browser/profiles/profile.cc6
-rw-r--r--chrome/browser/profiles/profile_dependency_manager.cc61
-rw-r--r--chrome/browser/profiles/profile_dependency_manager.h12
-rw-r--r--chrome/browser/profiles/profile_impl.cc8
-rw-r--r--chrome/browser/profiles/profile_keyed_service_factory.cc8
-rw-r--r--chrome/browser/profiles/profile_keyed_service_factory.h12
-rw-r--r--chrome/browser/search_engines/template_url_service_factory.cc4
-rw-r--r--chrome/browser/search_engines/template_url_service_factory.h1
-rw-r--r--chrome/browser/sessions/session_service_factory.cc8
-rw-r--r--chrome/browser/sessions/session_service_factory.h2
-rw-r--r--chrome/browser/sessions/tab_restore_service_factory.cc4
-rw-r--r--chrome/browser/sessions/tab_restore_service_factory.h1
-rw-r--r--chrome/test/testing_profile.cc12
15 files changed, 118 insertions, 31 deletions
diff --git a/chrome/browser/background/background_contents_service_factory.cc b/chrome/browser/background/background_contents_service_factory.cc
index 51b5ffd..d9139dc 100644
--- a/chrome/browser/background/background_contents_service_factory.cc
+++ b/chrome/browser/background/background_contents_service_factory.cc
@@ -38,3 +38,11 @@ ProfileKeyedService* BackgroundContentsServiceFactory::BuildServiceInstanceFor(
bool BackgroundContentsServiceFactory::ServiceHasOwnInstanceInIncognito() {
return true;
}
+
+bool BackgroundContentsServiceFactory::ServiceIsCreatedWithProfile() {
+ return true;
+}
+
+bool BackgroundContentsServiceFactory::ServiceIsNULLWhileTesting() {
+ return true;
+}
diff --git a/chrome/browser/background/background_contents_service_factory.h b/chrome/browser/background/background_contents_service_factory.h
index 18973a4..131f617 100644
--- a/chrome/browser/background/background_contents_service_factory.h
+++ b/chrome/browser/background/background_contents_service_factory.h
@@ -32,6 +32,8 @@ class BackgroundContentsServiceFactory : public ProfileKeyedServiceFactory {
Profile* profile) const OVERRIDE;
// Use a separate background contents service for incognito.
virtual bool ServiceHasOwnInstanceInIncognito() OVERRIDE;
+ virtual bool ServiceIsCreatedWithProfile() OVERRIDE;
+ virtual bool ServiceIsNULLWhileTesting() OVERRIDE;
};
#endif // CHROME_BROWSER_BACKGROUND_BACKGROUND_CONTENTS_SERVICE_FACTORY_H_
diff --git a/chrome/browser/profiles/profile.cc b/chrome/browser/profiles/profile.cc
index 24a14d8..86f7a79 100644
--- a/chrome/browser/profiles/profile.cc
+++ b/chrome/browser/profiles/profile.cc
@@ -222,15 +222,11 @@ class OffTheRecordProfileImpl : public Profile,
prefs_(real_profile->GetOffTheRecordPrefs()),
ALLOW_THIS_IN_INITIALIZER_LIST(io_data_(this)),
start_time_(Time::Now()) {
-#ifndef NDEBUG
- ProfileDependencyManager::GetInstance()->ProfileNowExists(this);
-#endif
-
extension_process_manager_.reset(ExtensionProcessManager::Create(this));
BrowserList::AddObserver(this);
- BackgroundContentsServiceFactory::GetForProfile(this);
+ ProfileDependencyManager::GetInstance()->CreateProfileServices(this, false);
DCHECK(real_profile->GetPrefs()->GetBoolean(prefs::kIncognitoEnabled));
diff --git a/chrome/browser/profiles/profile_dependency_manager.cc b/chrome/browser/profiles/profile_dependency_manager.cc
index e6479ad..154a332 100644
--- a/chrome/browser/profiles/profile_dependency_manager.cc
+++ b/chrome/browser/profiles/profile_dependency_manager.cc
@@ -8,12 +8,42 @@
#include <deque>
#include <iterator>
+#include "chrome/browser/background/background_contents_service_factory.h"
#include "chrome/browser/profiles/profile_keyed_service.h"
#include "chrome/browser/profiles/profile_keyed_service_factory.h"
+#include "chrome/browser/search_engines/template_url_service_factory.h"
+#include "chrome/browser/sessions/session_service_factory.h"
+#include "chrome/browser/sessions/tab_restore_service_factory.h"
#include "content/common/notification_service.h"
class Profile;
+namespace {
+
+bool g_initialized = false;
+
+// This method gets the instance of each ServiceFactory. We do this so that
+// each ServiceFactory initializes iteslf and registers its dependencies with
+// the global PreferenceDependencyManager. We need to have a complete
+// dependency graph when we create a profile so we can dispatch the profile
+// creation message to the services that want to create their services at
+// profile creation time.
+//
+// TODO(erg): This needs to be something else. I don't think putting every
+// FooServiceFactory here will scale or is desireable long term.
+void AssertFactoriesBuilt() {
+ if (!g_initialized) {
+ BackgroundContentsServiceFactory::GetInstance();
+ SessionServiceFactory::GetInstance();
+ TabRestoreServiceFactory::GetInstance();
+ TemplateURLServiceFactory::GetInstance();
+
+ g_initialized = true;
+ }
+}
+
+} // namespace
+
void ProfileDependencyManager::AddComponent(
ProfileKeyedServiceFactory* component) {
all_components_.push_back(component);
@@ -46,6 +76,33 @@ void ProfileDependencyManager::AddEdge(ProfileKeyedServiceFactory* depended,
destruction_order_.clear();
}
+void ProfileDependencyManager::CreateProfileServices(Profile* profile,
+ bool is_testing_profile) {
+#ifndef NDEBUG
+ // Unmark |profile| as dead. This exists because of unit tests, which will
+ // often have similar stack structures. 0xWhatever might be created, go out
+ // of scope, and then a new Profile object might be created at 0xWhatever.
+ dead_profile_pointers_.erase(profile);
+#endif
+
+ AssertFactoriesBuilt();
+
+ if (destruction_order_.empty())
+ BuildDestructionOrder();
+
+ // Iterate in reverse destruction order for creation.
+ for (std::vector<ProfileKeyedServiceFactory*>::reverse_iterator rit =
+ destruction_order_.rbegin(); rit != destruction_order_.rend();
+ ++rit) {
+ if (is_testing_profile && (*rit)->ServiceIsNULLWhileTesting()) {
+ (*rit)->SetTestingFactory(profile, NULL);
+ } else if ((*rit)->ServiceIsCreatedWithProfile()) {
+ // Create the service.
+ (*rit)->GetServiceForProfile(profile, true);
+ }
+ }
+}
+
void ProfileDependencyManager::DestroyProfileServices(Profile* profile) {
if (destruction_order_.empty())
BuildDestructionOrder();
@@ -67,10 +124,6 @@ void ProfileDependencyManager::DestroyProfileServices(Profile* profile) {
}
#ifndef NDEBUG
-void ProfileDependencyManager::ProfileNowExists(Profile* profile) {
- dead_profile_pointers_.erase(profile);
-}
-
void ProfileDependencyManager::AssertProfileWasntDestroyed(Profile* profile) {
if (dead_profile_pointers_.find(profile) != dead_profile_pointers_.end()) {
NOTREACHED() << "Attempted to access a Profile that was ShutDown(). This "
diff --git a/chrome/browser/profiles/profile_dependency_manager.h b/chrome/browser/profiles/profile_dependency_manager.h
index b477bb7..6dc5c9f 100644
--- a/chrome/browser/profiles/profile_dependency_manager.h
+++ b/chrome/browser/profiles/profile_dependency_manager.h
@@ -31,6 +31,13 @@ class ProfileDependencyManager {
void AddEdge(ProfileKeyedServiceFactory* depended,
ProfileKeyedServiceFactory* dependee);
+ // Called by each Profile to alert us of its creation. Several services want
+ // to be started when a profile is created. Testing configuration is also
+ // done at this time. (If you want your ProfileKeyedService to be started
+ // with the Profile, override ProfileKeyedServiceFactory::
+ // ServiceIsCreatedWithProfile() to return true.)
+ void CreateProfileServices(Profile* profile, bool is_testing_profile);
+
// Called by each Profile to alert us that we should destroy services
// associated with it.
//
@@ -44,11 +51,6 @@ class ProfileDependencyManager {
void DestroyProfileServices(Profile* profile);
#ifndef NDEBUG
- // Unmark |profile| as dead. This exists because of unit tests, which will
- // often have similar stack structures. 0xWhatever might be created, go out
- // of scope, and then a new Profile object might be created at 0xWhatever.
- void ProfileNowExists(Profile* profile);
-
// Debugging assertion called as part of GetServiceForProfile in debug
// mode. This will NOTREACHED() whenever the user is trying to access a stale
// Profile*.
diff --git a/chrome/browser/profiles/profile_impl.cc b/chrome/browser/profiles/profile_impl.cc
index 91165fc..b5c8c49 100644
--- a/chrome/browser/profiles/profile_impl.cc
+++ b/chrome/browser/profiles/profile_impl.cc
@@ -303,10 +303,6 @@ ProfileImpl::ProfileImpl(const FilePath& path,
DCHECK(!path.empty()) << "Using an empty path will attempt to write " <<
"profile files to the root directory!";
-#ifndef NDEBUG
- ProfileDependencyManager::GetInstance()->ProfileNowExists(this);
-#endif
-
create_session_service_timer_.Start(
TimeDelta::FromMilliseconds(kCreateSessionServiceDelayMS), this,
&ProfileImpl::EnsureSessionServiceCreated);
@@ -379,8 +375,6 @@ void ProfileImpl::DoFinalInit() {
g_browser_process->background_mode_manager()->RegisterProfile(this);
#endif
- BackgroundContentsServiceFactory::GetForProfile(this);
-
extension_info_map_ = new ExtensionInfoMap();
InitRegisteredProtocolHandlers();
@@ -873,6 +867,8 @@ void ProfileImpl::OnPrefsLoaded(bool success) {
GetPath().AppendASCII(ExtensionService::kInstallDirectoryName),
GetExtensionPrefValueMap()));
+ ProfileDependencyManager::GetInstance()->CreateProfileServices(this, false);
+
DCHECK(!net_pref_observer_.get());
net_pref_observer_.reset(
new NetPrefObserver(prefs_.get(), GetPrerenderManager()));
diff --git a/chrome/browser/profiles/profile_keyed_service_factory.cc b/chrome/browser/profiles/profile_keyed_service_factory.cc
index e13fbf5..7ded5bf 100644
--- a/chrome/browser/profiles/profile_keyed_service_factory.cc
+++ b/chrome/browser/profiles/profile_keyed_service_factory.cc
@@ -107,6 +107,14 @@ bool ProfileKeyedServiceFactory::ServiceHasOwnInstanceInIncognito() {
return false;
}
+bool ProfileKeyedServiceFactory::ServiceIsCreatedWithProfile() {
+ return false;
+}
+
+bool ProfileKeyedServiceFactory::ServiceIsNULLWhileTesting() {
+ return false;
+}
+
void ProfileKeyedServiceFactory::ProfileShutdown(Profile* profile) {
std::map<Profile*, ProfileKeyedService*>::iterator it =
mapping_.find(profile);
diff --git a/chrome/browser/profiles/profile_keyed_service_factory.h b/chrome/browser/profiles/profile_keyed_service_factory.h
index f805db7..90c4308 100644
--- a/chrome/browser/profiles/profile_keyed_service_factory.h
+++ b/chrome/browser/profiles/profile_keyed_service_factory.h
@@ -75,6 +75,18 @@ class ProfileKeyedServiceFactory {
virtual bool ServiceRedirectedInIncognito();
virtual bool ServiceHasOwnInstanceInIncognito();
+ // By default, we create instances of a service lazily and wait until
+ // GetForProfile() is called on our subclass. Some services need to be
+ // created as soon as the Profile has been brought up.
+ virtual bool ServiceIsCreatedWithProfile();
+
+ // By default, TestingProfiles will be treated like normal profiles. You can
+ // override this so that by default, the service associated with the
+ // TestingProfile is NULL. (This is just a shortcut around
+ // SetTestingFactory() to make sure our profiles don't directly refer to the
+ // services they use.)
+ virtual bool ServiceIsNULLWhileTesting();
+
// A helper object actually listens for notifications about Profile
// destruction, calculates the order in which things are destroyed and then
// does a two pass shutdown.
diff --git a/chrome/browser/search_engines/template_url_service_factory.cc b/chrome/browser/search_engines/template_url_service_factory.cc
index e344163..ddbe5a5 100644
--- a/chrome/browser/search_engines/template_url_service_factory.cc
+++ b/chrome/browser/search_engines/template_url_service_factory.cc
@@ -36,6 +36,10 @@ bool TemplateURLServiceFactory::ServiceRedirectedInIncognito() {
return true;
}
+bool TemplateURLServiceFactory::ServiceIsNULLWhileTesting() {
+ return true;
+}
+
void TemplateURLServiceFactory::ProfileShutdown(Profile* profile) {
// We shutdown AND destroy the TemplateURLService during this pass.
// TemplateURLService schedules a task on the WebDataService from its
diff --git a/chrome/browser/search_engines/template_url_service_factory.h b/chrome/browser/search_engines/template_url_service_factory.h
index 703d586..8d3dbe2 100644
--- a/chrome/browser/search_engines/template_url_service_factory.h
+++ b/chrome/browser/search_engines/template_url_service_factory.h
@@ -29,6 +29,7 @@ class TemplateURLServiceFactory : public ProfileKeyedServiceFactory {
// ProfileKeyedServiceFactory:
virtual ProfileKeyedService* BuildServiceInstanceFor(Profile* profile) const;
virtual bool ServiceRedirectedInIncognito();
+ virtual bool ServiceIsNULLWhileTesting();
virtual void ProfileShutdown(Profile* profile);
virtual void ProfileDestroyed(Profile* profile);
};
diff --git a/chrome/browser/sessions/session_service_factory.cc b/chrome/browser/sessions/session_service_factory.cc
index 3a93dfb..8f1ba30 100644
--- a/chrome/browser/sessions/session_service_factory.cc
+++ b/chrome/browser/sessions/session_service_factory.cc
@@ -54,3 +54,11 @@ ProfileKeyedService* SessionServiceFactory::BuildServiceInstanceFor(
service->ResetFromCurrentBrowsers();
return service;
}
+
+bool SessionServiceFactory::ServiceIsCreatedWithProfile() {
+ return true;
+}
+
+bool SessionServiceFactory::ServiceIsNULLWhileTesting() {
+ return true;
+}
diff --git a/chrome/browser/sessions/session_service_factory.h b/chrome/browser/sessions/session_service_factory.h
index 213d2b6..eb46e653 100644
--- a/chrome/browser/sessions/session_service_factory.h
+++ b/chrome/browser/sessions/session_service_factory.h
@@ -55,6 +55,8 @@ class SessionServiceFactory : public ProfileKeyedServiceFactory {
// ProfileKeyedServiceFactory:
virtual ProfileKeyedService* BuildServiceInstanceFor(Profile* profile) const;
+ virtual bool ServiceIsCreatedWithProfile();
+ virtual bool ServiceIsNULLWhileTesting();
};
#endif // CHROME_BROWSER_SESSIONS_SESSION_SERVICE_FACTORY_H_
diff --git a/chrome/browser/sessions/tab_restore_service_factory.cc b/chrome/browser/sessions/tab_restore_service_factory.cc
index 73f793f..b35ffab 100644
--- a/chrome/browser/sessions/tab_restore_service_factory.cc
+++ b/chrome/browser/sessions/tab_restore_service_factory.cc
@@ -38,3 +38,7 @@ ProfileKeyedService* TabRestoreServiceFactory::BuildServiceInstanceFor(
service = new TabRestoreService(profile);
return service;
}
+
+bool TabRestoreServiceFactory::ServiceIsNULLWhileTesting() {
+ return true;
+}
diff --git a/chrome/browser/sessions/tab_restore_service_factory.h b/chrome/browser/sessions/tab_restore_service_factory.h
index d20720f9..b46ea96 100644
--- a/chrome/browser/sessions/tab_restore_service_factory.h
+++ b/chrome/browser/sessions/tab_restore_service_factory.h
@@ -30,6 +30,7 @@ class TabRestoreServiceFactory : public ProfileKeyedServiceFactory {
// ProfileKeyedServiceFactory:
virtual ProfileKeyedService* BuildServiceInstanceFor(Profile* profile) const;
+ virtual bool ServiceIsNULLWhileTesting();
};
#endif // CHROME_BROWSER_SESSIONS_TAB_RESTORE_SERVICE_FACTORY_H_
diff --git a/chrome/test/testing_profile.cc b/chrome/test/testing_profile.cc
index 4778a98..3a47753 100644
--- a/chrome/test/testing_profile.cc
+++ b/chrome/test/testing_profile.cc
@@ -13,7 +13,6 @@
#include "base/path_service.h"
#include "base/string_number_conversions.h"
#include "chrome/browser/autocomplete/autocomplete_classifier.h"
-#include "chrome/browser/background/background_contents_service_factory.h"
#include "chrome/browser/bookmarks/bookmark_model.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/content_settings/host_content_settings_map.h"
@@ -38,8 +37,6 @@
#include "chrome/browser/search_engines/template_url_fetcher.h"
#include "chrome/browser/search_engines/template_url_service.h"
#include "chrome/browser/search_engines/template_url_service_factory.h"
-#include "chrome/browser/sessions/session_service_factory.h"
-#include "chrome/browser/sessions/tab_restore_service_factory.h"
#include "chrome/browser/sync/profile_sync_service_mock.h"
#include "chrome/browser/ui/find_bar/find_bar_state.h"
#include "chrome/browser/ui/webui/chrome_url_data_manager.h"
@@ -129,9 +126,7 @@ TestingProfile::TestingProfile()
incognito_(false),
last_session_exited_cleanly_(true),
profile_dependency_manager_(ProfileDependencyManager::GetInstance()) {
-#ifndef NDEBUG
- profile_dependency_manager_->ProfileNowExists(this);
-#endif
+ profile_dependency_manager_->CreateProfileServices(this, true);
if (!temp_dir_.CreateUniqueTempDir()) {
LOG(ERROR) << "Failed to create unique temporary directory.";
@@ -158,13 +153,8 @@ TestingProfile::TestingProfile()
}
// Install profile keyed service factory hooks for dummy/test services
- BackgroundContentsServiceFactory::GetInstance()->SetTestingFactory(
- this, NULL);
DesktopNotificationServiceFactory::GetInstance()->SetTestingFactory(
this, CreateTestDesktopNotificationService);
- SessionServiceFactory::GetInstance()->SetTestingFactory(this, NULL);
- TabRestoreServiceFactory::GetInstance()->SetTestingFactory(this, NULL);
- TemplateURLServiceFactory::GetInstance()->SetTestingFactory(this, NULL);
NotificationService::current()->Notify(
chrome::NOTIFICATION_PROFILE_CREATED,