diff options
34 files changed, 447 insertions, 899 deletions
diff --git a/chrome/browser/app_controller_mac.mm b/chrome/browser/app_controller_mac.mm index 3be6c92..6934219 100644 --- a/chrome/browser/app_controller_mac.mm +++ b/chrome/browser/app_controller_mac.mm @@ -599,17 +599,18 @@ void RecordLastRunAppBundlePath() { if (!profile_manager) return YES; - std::vector<Profile*> profiles(profile_manager->GetLoadedProfiles()); - for (size_t i = 0; i < profiles.size(); ++i) { - DownloadManager* download_manager = profiles[i]->GetDownloadManager(); + ProfileManager::const_iterator it = profile_manager->begin(); + for (; it != profile_manager->end(); ++it) { + Profile* profile = *it; + DownloadManager* download_manager = profile->GetDownloadManager(); if (download_manager && download_manager->in_progress_count() > 0) { int downloadCount = download_manager->in_progress_count(); if ([self userWillWaitForInProgressDownloads:downloadCount]) { // Create a new browser window (if necessary) and navigate to the // downloads page if the user chooses to wait. - Browser* browser = BrowserList::FindBrowserWithProfile(profiles[i]); + Browser* browser = BrowserList::FindBrowserWithProfile(profile); if (!browser) { - browser = Browser::Create(profiles[i]); + browser = Browser::Create(profile); browser->window()->Show(); } DCHECK(browser); @@ -983,8 +984,9 @@ void RecordLastRunAppBundlePath() { } - (Profile*)defaultProfile { + // TODO(jrg): Find a better way to get the "default" profile. if (g_browser_process->profile_manager()) - return g_browser_process->profile_manager()->GetDefaultProfile(); + return *g_browser_process->profile_manager()->begin(); return NULL; } diff --git a/chrome/browser/automation/testing_automation_provider.cc b/chrome/browser/automation/testing_automation_provider.cc index 2a344d7..a2d9055 100644 --- a/chrome/browser/automation/testing_automation_provider.cc +++ b/chrome/browser/automation/testing_automation_provider.cc @@ -2563,10 +2563,10 @@ void TestingAutomationProvider::GetBrowserInfo( // item per extension process. ListValue* extension_processes = new ListValue; ProfileManager* profile_manager = g_browser_process->profile_manager(); - std::vector<Profile*> profiles(profile_manager->GetLoadedProfiles()); - for (size_t i = 0; i < profiles.size(); ++i) { + for (ProfileManager::const_iterator it = profile_manager->begin(); + it != profile_manager->end(); ++it) { ExtensionProcessManager* process_manager = - profiles[i]->GetExtensionProcessManager(); + (*it)->GetExtensionProcessManager(); if (!process_manager) continue; ExtensionProcessManager::const_iterator jt; diff --git a/chrome/browser/browser_main.cc b/chrome/browser/browser_main.cc index 6c5a59b..746ae30 100644 --- a/chrome/browser/browser_main.cc +++ b/chrome/browser/browser_main.cc @@ -955,8 +955,7 @@ void InitializeToolkit(const MainFunctionParams& parameters) { // Class is used to login using passed username and password. // The instance will be deleted upon success or failure. -class StubLogin : public chromeos::LoginStatusConsumer, - public chromeos::LoginUtils::Delegate { +class StubLogin : public chromeos::LoginStatusConsumer { public: explicit StubLogin(std::string username, std::string password) { authenticator_ = chromeos::LoginUtils::Get()->CreateAuthenticator(this); @@ -977,17 +976,10 @@ class StubLogin : public chromeos::LoginStatusConsumer, const std::string& password, const GaiaAuthConsumer::ClientLoginResult& credentials, bool pending_requests) { - // Will call OnProfilePrepared in the end. - chromeos::LoginUtils::Get()->PrepareProfile(username, - password, - credentials, - pending_requests, - this); - } - - // LoginUtils::Delegate implementation: - virtual void OnProfilePrepared(Profile* profile) { - chromeos::LoginUtils::DoBrowserLaunch(profile); + chromeos::LoginUtils::Get()->CompleteLogin(username, + password, + credentials, + pending_requests); delete this; } diff --git a/chrome/browser/browser_process_impl.cc b/chrome/browser/browser_process_impl.cc index b14403e..c521e11 100644 --- a/chrome/browser/browser_process_impl.cc +++ b/chrome/browser/browser_process_impl.cc @@ -324,9 +324,8 @@ void BrowserProcessImpl::EndSession() { // Mark all the profiles as clean. ProfileManager* pm = profile_manager(); - std::vector<Profile*> profiles(pm->GetLoadedProfiles()); - for (size_t i = 0; i < profiles.size(); ++i) - profiles[i]->MarkAsCleanShutdown(); + for (ProfileManager::const_iterator i = pm->begin(); i != pm->end(); ++i) + (*i)->MarkAsCleanShutdown(); // Tell the metrics service it was cleanly shutdown. MetricsService* metrics = g_browser_process->metrics_service(); diff --git a/chrome/browser/chromeos/login/existing_user_controller.cc b/chrome/browser/chromeos/login/existing_user_controller.cc index d080e73..dcba46b 100644 --- a/chrome/browser/chromeos/login/existing_user_controller.cc +++ b/chrome/browser/chromeos/login/existing_user_controller.cc @@ -16,6 +16,7 @@ #include "chrome/browser/chromeos/cros/network_library.h" #include "chrome/browser/chromeos/login/helper.h" #include "chrome/browser/chromeos/login/login_display_host.h" +#include "chrome/browser/chromeos/login/login_utils.h" #include "chrome/browser/chromeos/login/views_login_display.h" #include "chrome/browser/chromeos/login/wizard_accessibility_helper.h" #include "chrome/browser/chromeos/login/wizard_controller.h" @@ -320,14 +321,6 @@ void ExistingUserController::OnLoginSuccess( const std::string& password, const GaiaAuthConsumer::ClientLoginResult& credentials, bool pending_requests) { - bool known_user = UserManager::Get()->IsKnownUser(username); - bool login_only = - CommandLine::ForCurrentProcess()->GetSwitchValueASCII( - switches::kLoginScreen) == WizardController::kLoginScreenName; - ready_for_browser_launch_ = known_user || login_only; - - two_factor_credentials_ = credentials.two_factor; - // LoginPerformer instance will delete itself once online auth result is OK. // In case of failure it'll bring up ScreenLock and ask for // correct password/display error message. @@ -336,19 +329,12 @@ void ExistingUserController::OnLoginSuccess( login_performer_->set_delegate(NULL); LoginPerformer* performer = login_performer_.release(); performer = NULL; - - // Will call OnProfilePrepared() in the end. - LoginUtils::Get()->PrepareProfile(username, - password, - credentials, - pending_requests, - this); - -} - -void ExistingUserController::OnProfilePrepared(Profile* profile) { + bool known_user = UserManager::Get()->IsKnownUser(username); + bool login_only = + CommandLine::ForCurrentProcess()->GetSwitchValueASCII( + switches::kLoginScreen) == WizardController::kLoginScreenName; // TODO(nkostylev): May add login UI implementation callback call. - if (!ready_for_browser_launch_) { + if (!known_user && !login_only) { #if defined(OFFICIAL_BUILD) CommandLine::ForCurrentProcess()->AppendArg(kGetStartedURL); #endif // OFFICIAL_BUILD @@ -359,18 +345,29 @@ void ExistingUserController::OnProfilePrepared(Profile* profile) { CommandLine::ForCurrentProcess()->AppendArg(initial_start_page_); } - if (two_factor_credentials_) { + if (credentials.two_factor) { // If we have a two factor error and and this is a new user, // load the personal settings page. // TODO(stevenjb): direct the user to a lightweight sync login page. CommandLine::ForCurrentProcess()->AppendArg(kSettingsSyncLoginURL); } + // For new user login don't launch browser until we pass image screen. + LoginUtils::Get()->EnableBrowserLaunch(false); + LoginUtils::Get()->CompleteLogin(username, + password, + credentials, + pending_requests); + ActivateWizard(WizardController::IsDeviceRegistered() ? WizardController::kUserImageScreenName : WizardController::kRegistrationScreenName); } else { - LoginUtils::DoBrowserLaunch(profile); + LoginUtils::Get()->CompleteLogin(username, + password, + credentials, + pending_requests); + // Delay deletion as we're on the stack. host_->OnSessionStart(); } diff --git a/chrome/browser/chromeos/login/existing_user_controller.h b/chrome/browser/chromeos/login/existing_user_controller.h index aff1bfc..d7a02d6 100644 --- a/chrome/browser/chromeos/login/existing_user_controller.h +++ b/chrome/browser/chromeos/login/existing_user_controller.h @@ -16,7 +16,6 @@ #include "chrome/browser/chromeos/login/captcha_view.h" #include "chrome/browser/chromeos/login/login_display.h" #include "chrome/browser/chromeos/login/login_performer.h" -#include "chrome/browser/chromeos/login/login_utils.h" #include "chrome/browser/chromeos/login/ownership_status_checker.h" #include "chrome/browser/chromeos/login/password_changed_view.h" #include "chrome/browser/chromeos/login/user_manager.h" @@ -42,7 +41,6 @@ class UserCrosSettingsProvider; class ExistingUserController : public LoginDisplay::Delegate, public NotificationObserver, public LoginPerformer::Delegate, - public LoginUtils::Delegate, public CaptchaView::Delegate, public PasswordChangedView::Delegate { public: @@ -93,9 +91,6 @@ class ExistingUserController : public LoginDisplay::Delegate, const GaiaAuthConsumer::ClientLoginResult& credentials); virtual void WhiteListCheckFailed(const std::string& email); - // LoginUtils::Delegate implementation: - virtual void OnProfilePrepared(Profile* profile); - // CaptchaView::Delegate: virtual void OnCaptchaEntered(const std::string& captcha); @@ -164,12 +159,6 @@ class ExistingUserController : public LoginDisplay::Delegate, // Factory of callbacks. ScopedRunnableMethodFactory<ExistingUserController> method_factory_; - // Whether everything is ready to launch the browser. - bool ready_for_browser_launch_; - - // Whether two factor credentials were used. - bool two_factor_credentials_; - // Used to verify ownership before starting enterprise enrollment. scoped_ptr<OwnershipStatusChecker> ownership_checker_; diff --git a/chrome/browser/chromeos/login/login_performer.cc b/chrome/browser/chromeos/login/login_performer.cc index 8d333e6..4aad0fa 100644 --- a/chrome/browser/chromeos/login/login_performer.cc +++ b/chrome/browser/chromeos/login/login_performer.cc @@ -135,37 +135,29 @@ void LoginPerformer::OnLoginSuccess( pending_requests); return; } else { - // Online login has succeeded. DCHECK(!pending_requests) << "Pending request w/o delegate_ should not happen!"; - // It is not guaranted, that profile creation has been finished yet. So use - // async version here. - credentials_ = credentials; - ProfileManager::CreateDefaultProfileAsync(this); - } -} - -void LoginPerformer::OnProfileCreated(Profile* profile) { - CHECK(profile); - - LoginUtils::Get()->FetchCookies(profile, credentials_); - LoginUtils::Get()->FetchTokens(profile, credentials_); - credentials_ = GaiaAuthConsumer::ClientLoginResult(); - - // Don't unlock screen if it was locked while we're waiting - // for initial online auth. - if (ScreenLocker::default_screen_locker() && - !initial_online_auth_pending_) { - DVLOG(1) << "Online login OK - unlocking screen."; - RequestScreenUnlock(); - // Do not delete itself just yet, wait for unlock. - // See ResolveScreenUnlocked(). - return; + // Online login has succeeded. + Profile* profile = + g_browser_process->profile_manager()->GetDefaultProfile(); + LoginUtils::Get()->FetchCookies(profile, credentials); + LoginUtils::Get()->FetchTokens(profile, credentials); + + // Don't unlock screen if it was locked while we're waiting + // for initial online auth. + if (ScreenLocker::default_screen_locker() && + !initial_online_auth_pending_) { + DVLOG(1) << "Online login OK - unlocking screen."; + RequestScreenUnlock(); + // Do not delete itself just yet, wait for unlock. + // See ResolveScreenUnlocked(). + return; + } + initial_online_auth_pending_ = false; + // There's nothing else that's holding LP from deleting itself - + // no ScreenLock, no pending requests. + MessageLoop::current()->DeleteSoon(FROM_HERE, this); } - initial_online_auth_pending_ = false; - // There's nothing else that's holding LP from deleting itself - - // no ScreenLock, no pending requests. - MessageLoop::current()->DeleteSoon(FROM_HERE, this); } void LoginPerformer::OnOffTheRecordLoginSuccess() { diff --git a/chrome/browser/chromeos/login/login_performer.h b/chrome/browser/chromeos/login/login_performer.h index fb847c7..ff3c829 100644 --- a/chrome/browser/chromeos/login/login_performer.h +++ b/chrome/browser/chromeos/login/login_performer.h @@ -14,7 +14,6 @@ #include "chrome/browser/chromeos/login/authenticator.h" #include "chrome/browser/chromeos/login/login_status_consumer.h" #include "chrome/browser/chromeos/login/signed_settings_helper.h" -#include "chrome/browser/profiles/profile_manager.h" #include "chrome/common/net/gaia/google_service_auth_error.h" #include "content/common/notification_observer.h" #include "content/common/notification_registrar.h" @@ -53,8 +52,7 @@ namespace chromeos { // 2. Pending online auth request. class LoginPerformer : public LoginStatusConsumer, public SignedSettingsHelper::Callback, - public NotificationObserver, - public ProfileManager::Observer { + public NotificationObserver { public: // Delegate class to get notifications from the LoginPerformer. class Delegate : public LoginStatusConsumer { @@ -119,9 +117,6 @@ class LoginPerformer : public LoginStatusConsumer, void set_delegate(Delegate* delegate) { delegate_ = delegate; } private: - // ProfeleManager::Observer implementation: - void OnProfileCreated(Profile* profile); - // Requests screen lock and subscribes to screen lock notifications. void RequestScreenLock(); @@ -188,8 +183,6 @@ class LoginPerformer : public LoginStatusConsumer, // is locked during that stage. No need to resolve screen lock action then. bool initial_online_auth_pending_; - GaiaAuthConsumer::ClientLoginResult credentials_; - ScopedRunnableMethodFactory<LoginPerformer> method_factory_; DISALLOW_COPY_AND_ASSIGN(LoginPerformer); diff --git a/chrome/browser/chromeos/login/login_utils.cc b/chrome/browser/chromeos/login/login_utils.cc index 5045ba9..f71a5a5 100644 --- a/chrome/browser/chromeos/login/login_utils.cc +++ b/chrome/browser/chromeos/login/login_utils.cc @@ -103,19 +103,20 @@ class ResetDefaultProxyConfigServiceTask : public Task { } // namespace -class LoginUtilsImpl : public LoginUtils, - public ProfileManager::Observer { +class LoginUtilsImpl : public LoginUtils { public: LoginUtilsImpl() - : background_view_(NULL) { + : browser_launch_enabled_(true), + background_view_(NULL) { } - virtual void PrepareProfile( + // Invoked after the user has successfully logged in. This launches a browser + // and does other bookkeeping after logging in. + virtual void CompleteLogin( const std::string& username, const std::string& password, const GaiaAuthConsumer::ClientLoginResult& credentials, - bool pending_requests, - LoginUtils::Delegate* delegate); + bool pending_requests); // Invoked after the tmpfs is successfully mounted. // Launches a browser in the incognito mode. @@ -129,6 +130,13 @@ class LoginUtilsImpl : public LoginUtils, // Authenticator and must delete it when done. virtual Authenticator* CreateAuthenticator(LoginStatusConsumer* consumer); + // Used to postpone browser launch via DoBrowserLaunch() if some post + // login screen is to be shown. + virtual void EnableBrowserLaunch(bool enable); + + // Returns if browser launch enabled now or not. + virtual bool IsBrowserLaunchEnabled() const; + // Warms the url used by authentication. virtual void PrewarmAuthentication(); @@ -149,9 +157,6 @@ class LoginUtilsImpl : public LoginUtils, // Gets the current background view. virtual chromeos::BackgroundView* GetBackgroundView(); - // ProfileManager::Observer implementation: - virtual void OnProfileCreated(Profile* profile); - protected: virtual std::string GetOffTheRecordCommandLine( const GURL& start_url, @@ -162,17 +167,12 @@ class LoginUtilsImpl : public LoginUtils, // Check user's profile for kApplicationLocale setting. void RespectLocalePreference(Profile* pref); + // Indicates if DoBrowserLaunch will actually launch the browser or not. + bool browser_launch_enabled_; + // The current background view. chromeos::BackgroundView* background_view_; - std::string username_; - std::string password_; - GaiaAuthConsumer::ClientLoginResult credentials_; - bool pending_requests_; - - // Delegate to be fired when the profile will be prepared. - LoginUtils::Delegate* delegate_; - DISALLOW_COPY_AND_ASSIGN(LoginUtilsImpl); }; @@ -204,12 +204,11 @@ class LoginUtilsWrapper { DISALLOW_COPY_AND_ASSIGN(LoginUtilsWrapper); }; -void LoginUtilsImpl::PrepareProfile( +void LoginUtilsImpl::CompleteLogin( const std::string& username, const std::string& password, const GaiaAuthConsumer::ClientLoginResult& credentials, - bool pending_requests, - LoginUtils::Delegate* delegate) { + bool pending_requests) { BootTimesLoader* btl = BootTimesLoader::Get(); VLOG(1) << "Completing login for " << username; @@ -220,31 +219,30 @@ void LoginUtilsImpl::PrepareProfile( btl->AddLoginTimeMarker("StartedSession", false); } + bool first_login = !UserManager::Get()->IsKnownUser(username); UserManager::Get()->UserLoggedIn(username); btl->AddLoginTimeMarker("UserLoggedIn", false); + // Now get the new profile. + FilePath user_data_dir; + PathService::Get(chrome::DIR_USER_DATA, &user_data_dir); + ProfileManager* profile_manager = g_browser_process->profile_manager(); + // Switch log file as soon as possible. logging::RedirectChromeLogging(*(CommandLine::ForCurrentProcess())); btl->AddLoginTimeMarker("LoggingRedirected", false); - username_ = username; - password_ = password; - credentials_ = credentials; - pending_requests_ = pending_requests; - delegate_ = delegate; - - // The default profile will have been changed because the ProfileManager - // will process the notification that the UserManager sends out. - ProfileManager::CreateDefaultProfileAsync(this); -} - -void LoginUtilsImpl::OnProfileCreated(Profile* profile) { - CHECK(profile); - - BootTimesLoader* btl = BootTimesLoader::Get(); + Profile* profile = NULL; + { + // Loading user profile causes us to do blocking IO on UI thread. + // Temporarily allow it until we fix http://crosbug.com/11104 + base::ThreadRestrictions::ScopedAllowIO allow_io; + // The default profile will have been changed because the ProfileManager + // will process the notification that the UserManager sends out. + profile = profile_manager->GetDefaultProfile(user_data_dir); + } btl->AddLoginTimeMarker("UserProfileGotten", false); - bool first_login = !UserManager::Get()->IsKnownUser(username_); // Change the proxy configuration service of the default request context to // use the preference configuration from the logged-in profile. This ensures // that requests done through the default context use the proxy configuration @@ -268,11 +266,11 @@ void LoginUtilsImpl::OnProfileCreated(Profile* profile) { proxy_config_service)); // Since we're doing parallel authentication, only new user sign in - // would perform online auth before calling PrepareProfile. + // would perform online auth before calling CompleteLogin. // For existing users there's usually a pending online auth request. // Cookies will be fetched after it's is succeeded. - if (!pending_requests_) { - FetchCookies(profile, credentials_); + if (!pending_requests) { + FetchCookies(profile, credentials); } // Init extension event routers; this normally happens in browser_main @@ -292,16 +290,16 @@ void LoginUtilsImpl::OnProfileCreated(Profile* profile) { // For existing users there's usually a pending online auth request. // Tokens will be fetched after it's is succeeded. - if (!pending_requests_) { - FetchTokens(profile, credentials_); + if (!pending_requests) { + FetchTokens(profile, credentials); } btl->AddLoginTimeMarker("TokensGotten", false); // Set the CrOS user by getting this constructor run with the // user's email on first retrieval. - profile->GetProfileSyncService(username_)->SetPassphrase(password_, - false, - true); + profile->GetProfileSyncService(username)->SetPassphrase(password, + false, + true); btl->AddLoginTimeMarker("SyncStarted", false); // Own TPM device if, for any reason, it has not been done in EULA @@ -332,19 +330,13 @@ void LoginUtilsImpl::OnProfileCreated(Profile* profile) { // done yet to pull down policies from the domain admin. We'll take this // out when we get that done properly. // TODO(xiyuan): Remove this once enterprise feature is ready. - if (EndsWith(username_, "@google.com", true)) { + if (EndsWith(username, "@google.com", true)) { PrefService* pref_service = profile->GetPrefs(); pref_service->SetBoolean(prefs::kEnableScreenLock, true); } profile->OnLogin(); - - delegate_->OnProfilePrepared(profile); - - // TODO(altimofeev): Need to sanitize memory used to store password. - password_ = ""; - username_ = ""; - credentials_ = GaiaAuthConsumer::ClientLoginResult(); + DoBrowserLaunch(profile); } void LoginUtilsImpl::FetchCookies( @@ -523,6 +515,14 @@ Authenticator* LoginUtilsImpl::CreateAuthenticator( return new GoogleAuthenticator(consumer); } +void LoginUtilsImpl::EnableBrowserLaunch(bool enable) { + browser_launch_enabled_ = enable; +} + +bool LoginUtilsImpl::IsBrowserLaunchEnabled() const { + return browser_launch_enabled_; +} + // We use a special class for this so that it can be safely leaked if we // never connect. At shutdown the order is not well defined, and it's possible // for the infrastructure needed to unregister might be unstable and crash. @@ -580,6 +580,9 @@ void LoginUtils::Set(LoginUtils* mock) { void LoginUtils::DoBrowserLaunch(Profile* profile) { BootTimesLoader::Get()->AddLoginTimeMarker("BrowserLaunched", false); + // Browser launch was disabled due to some post login screen. + if (!LoginUtils::Get()->IsBrowserLaunchEnabled()) + return; // Update command line in case loose values were added. CommandLine::ForCurrentProcess()->InitFromArgv( diff --git a/chrome/browser/chromeos/login/login_utils.h b/chrome/browser/chromeos/login/login_utils.h index d0eaeb7..05a1a6c 100644 --- a/chrome/browser/chromeos/login/login_utils.h +++ b/chrome/browser/chromeos/login/login_utils.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -27,12 +27,6 @@ class LoginStatusConsumer; class LoginUtils { public: - class Delegate { - public: - // Called after profile is loaded and prepared for the session. - virtual void OnProfilePrepared(Profile* profile) = 0; - }; - // Get LoginUtils singleton object. If it was not set before, new default // instance will be created. static LoginUtils* Get(); @@ -46,14 +40,14 @@ class LoginUtils { virtual ~LoginUtils() {} - // Loads and prepares profile for the session. Fires |delegate| in the end. + // Invoked after the user has successfully logged in. This launches a browser + // and does other bookkeeping after logging in. // If |pending_requests| is true, there's a pending online auth request. - virtual void PrepareProfile( + virtual void CompleteLogin( const std::string& username, const std::string& password, const GaiaAuthConsumer::ClientLoginResult& credentials, - bool pending_requests, - Delegate* delegate) = 0; + bool pending_requests) = 0; // Invoked after the tmpfs is successfully mounted. // Asks session manager to restart Chrome in Browse Without Sign In mode. @@ -68,6 +62,13 @@ class LoginUtils { // Authenticator and must delete it when done. virtual Authenticator* CreateAuthenticator(LoginStatusConsumer* consumer) = 0; + // Used to postpone browser launch via DoBrowserLaunch() if some post + // login screen is to be shown. + virtual void EnableBrowserLaunch(bool enable) = 0; + + // Returns if browser launch enabled now or not. + virtual bool IsBrowserLaunchEnabled() const = 0; + // Prewarms the authentication network connection. virtual void PrewarmAuthentication() = 0; diff --git a/chrome/browser/chromeos/login/mock_authenticator.h b/chrome/browser/chromeos/login/mock_authenticator.h index 73c5352..4816442 100644 --- a/chrome/browser/chromeos/login/mock_authenticator.h +++ b/chrome/browser/chromeos/login/mock_authenticator.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -111,15 +111,12 @@ class MockLoginUtils : public LoginUtils { return false; } - virtual void PrepareProfile(const std::string& username, - const std::string& password, - const GaiaAuthConsumer::ClientLoginResult& res, - bool pending_requests, - Delegate* delegate) { + virtual void CompleteLogin(const std::string& username, + const std::string& password, + const GaiaAuthConsumer::ClientLoginResult& res, + bool pending_requests) { EXPECT_EQ(expected_username_, username); EXPECT_EQ(expected_password_, password); - // Profile hasn't been loaded. - delegate->OnProfilePrepared(NULL); } virtual void CompleteOffTheRecordLogin(const GURL& start_url) { @@ -133,6 +130,13 @@ class MockLoginUtils : public LoginUtils { consumer, expected_username_, expected_password_); } + virtual void EnableBrowserLaunch(bool enable) { + } + + virtual bool IsBrowserLaunchEnabled() const { + return true; + } + virtual void PrewarmAuthentication() { } diff --git a/chrome/browser/chromeos/login/screen_locker.cc b/chrome/browser/chromeos/login/screen_locker.cc index 0d74e11..09d7675 100644 --- a/chrome/browser/chromeos/login/screen_locker.cc +++ b/chrome/browser/chromeos/login/screen_locker.cc @@ -36,7 +36,6 @@ #include "chrome/browser/chromeos/view_ids.h" #include "chrome/browser/chromeos/wm_ipc.h" #include "chrome/browser/metrics/user_metrics.h" -#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/sync/profile_sync_service.h" #include "chrome/browser/ui/browser.h" diff --git a/chrome/browser/chromeos/login/wizard_controller.cc b/chrome/browser/chromeos/login/wizard_controller.cc index 02111db..d28a56c 100644 --- a/chrome/browser/chromeos/login/wizard_controller.cc +++ b/chrome/browser/chromeos/login/wizard_controller.cc @@ -550,6 +550,7 @@ void WizardController::OnUserImageSelected() { // Host will mark itself (and all controllers/windows) for deletion. host_->OnSessionStart(); // Launch browser after controller is deleted and its windows are closed. + chromeos::LoginUtils::Get()->EnableBrowserLaunch(true); BrowserThread::PostTask( BrowserThread::UI, FROM_HERE, diff --git a/chrome/browser/content_settings/content_settings_pref_provider_unittest.cc b/chrome/browser/content_settings/content_settings_pref_provider_unittest.cc index 105cb96..6f9827d 100644 --- a/chrome/browser/content_settings/content_settings_pref_provider_unittest.cc +++ b/chrome/browser/content_settings/content_settings_pref_provider_unittest.cc @@ -36,7 +36,7 @@ class ContentSettingsPrefService : public PrefService { : PrefService( managed_platform_prefs, managed_cloud_prefs, extension_prefs, command_line_prefs, user_prefs, recommended_platform_prefs, - recommended_cloud_prefs, default_store, NULL) {} + recommended_cloud_prefs, default_store) {} virtual ~ContentSettingsPrefService() {} }; } diff --git a/chrome/browser/debugger/extension_ports_remote_service.cc b/chrome/browser/debugger/extension_ports_remote_service.cc index 9db706c..b769ca0 100644 --- a/chrome/browser/debugger/extension_ports_remote_service.cc +++ b/chrome/browser/debugger/extension_ports_remote_service.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -121,11 +121,12 @@ ExtensionPortsRemoteService::ExtensionPortsRemoteService( LOG(WARNING) << "No profile manager for ExtensionPortsRemoteService"; return; } - - std::vector<Profile*> profiles(profile_manager->GetLoadedProfiles()); - for (size_t i = 0; i < profiles.size(); ++i) { - if (!profiles[i]->IsOffTheRecord()) { - service_ = profiles[i]->GetExtensionMessageService(); + for (ProfileManager::ProfileVector::const_iterator it + = profile_manager->begin(); + it != profile_manager->end(); + ++it) { + if (!(*it)->IsOffTheRecord()) { + service_ = (*it)->GetExtensionMessageService(); break; } } diff --git a/chrome/browser/extensions/extension_event_router_forwarder.cc b/chrome/browser/extensions/extension_event_router_forwarder.cc index 969c61d..5147453 100644 --- a/chrome/browser/extensions/extension_event_router_forwarder.cc +++ b/chrome/browser/extensions/extension_event_router_forwarder.cc @@ -80,11 +80,11 @@ void ExtensionEventRouterForwarder::HandleEvent( profile, extension_id, event_name, event_args, use_profile_to_restrict_events ? profile : NULL, event_url); } else { - std::vector<Profile*> profiles(profile_manager->GetLoadedProfiles()); - for (size_t i = 0; i < profiles.size(); ++i) { + ProfileManager::iterator i; + for (i = profile_manager->begin(); i != profile_manager->end(); ++i) { CallExtensionEventRouter( - profiles[i], extension_id, event_name, event_args, - use_profile_to_restrict_events ? profiles[i] : NULL, event_url); + *i, extension_id, event_name, event_args, + use_profile_to_restrict_events ? (*i) : NULL, event_url); } } } @@ -112,3 +112,4 @@ void ExtensionEventRouterForwarder::CallExtensionEventRouter( event_name, event_args, restrict_to_profile, event_url); } } + diff --git a/chrome/browser/extensions/extension_event_router_forwarder_unittest.cc b/chrome/browser/extensions/extension_event_router_forwarder_unittest.cc index 7d82ea5..ac4405e 100644 --- a/chrome/browser/extensions/extension_event_router_forwarder_unittest.cc +++ b/chrome/browser/extensions/extension_event_router_forwarder_unittest.cc @@ -52,8 +52,8 @@ class ExtensionEventRouterForwarderTest : public TestingBrowserProcessTest { profile1_ = new TestingProfile(); profile2_ = new TestingProfile(); - browser_process->profile_manager()->RegisterProfile(profile1_, true); - browser_process->profile_manager()->RegisterProfile(profile2_, true); + browser_process->profile_manager()->RegisterProfile(profile1_); + browser_process->profile_manager()->RegisterProfile(profile2_); } TestingProfile* CreateIncognitoProfile(TestingProfile* base) { diff --git a/chrome/browser/memory_purger.cc b/chrome/browser/memory_purger.cc index 80a884e..78d009d 100644 --- a/chrome/browser/memory_purger.cc +++ b/chrome/browser/memory_purger.cc @@ -98,10 +98,11 @@ void MemoryPurger::PurgeBrowser() { new PurgeMemoryIOHelper(g_browser_process->resource_dispatcher_host()-> safe_browsing_service())); ProfileManager* profile_manager = g_browser_process->profile_manager(); - std::vector<Profile*> profiles(profile_manager->GetLoadedProfiles()); - for (size_t i = 0; i < profiles.size(); ++i) { + for (ProfileManager::iterator i(profile_manager->begin()); + i != profile_manager->end(); ++i) { + Profile* profile = *i; purge_memory_io_helper->AddRequestContextGetter( - make_scoped_refptr(profiles[i]->GetRequestContext())); + make_scoped_refptr(profile->GetRequestContext())); // NOTE: Some objects below may be duplicates across profiles. We could // conceivably put all these in sets and then iterate over the sets. @@ -110,20 +111,20 @@ void MemoryPurger::PurgeBrowser() { // Spinning up the history service is expensive, so we avoid doing it if it // hasn't been done already. HistoryService* history_service = - profiles[i]->GetHistoryServiceWithoutCreating(); + profile->GetHistoryServiceWithoutCreating(); if (history_service) history_service->UnloadBackend(); // Unload all web databases (freeing memory used to cache sqlite). WebDataService* web_data_service = - profiles[i]->GetWebDataServiceWithoutCreating(); + profile->GetWebDataServiceWithoutCreating(); if (web_data_service) web_data_service->UnloadDatabase(); // Ask all WebKitContexts to purge memory (freeing memory used to cache // the LocalStorage sqlite DB). WebKitContext creation is basically free so // we don't bother with a "...WithoutCreating()" function. - profiles[i]->GetWebKitContext()->PurgeMemory(); + profile->GetWebKitContext()->PurgeMemory(); } BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, diff --git a/chrome/browser/prefs/pref_service.cc b/chrome/browser/prefs/pref_service.cc index e960eb4..0a2f381 100644 --- a/chrome/browser/prefs/pref_service.cc +++ b/chrome/browser/prefs/pref_service.cc @@ -25,6 +25,7 @@ #include "chrome/browser/prefs/overlay_persistent_pref_store.h" #include "chrome/browser/prefs/pref_notifier_impl.h" #include "chrome/browser/prefs/pref_value_store.h" +#include "chrome/common/json_pref_store.h" #include "content/browser/browser_thread.h" #include "content/common/notification_service.h" #include "grit/chromium_strings.h" @@ -87,15 +88,6 @@ void NotifyReadError(PrefService* pref, int message_id) { PrefService* PrefService::CreatePrefService(const FilePath& pref_filename, PrefStore* extension_prefs, Profile* profile) { - return CreatePrefServiceAsync(pref_filename, extension_prefs, profile, NULL); -} - -// static -PrefService* PrefService::CreatePrefServiceAsync( - const FilePath& pref_filename, - PrefStore* extension_prefs, - Profile* profile, - PrefService::Delegate* delegate) { using policy::ConfigurationPolicyPrefStore; #if defined(OS_LINUX) @@ -129,7 +121,7 @@ PrefService* PrefService::CreatePrefServiceAsync( return new PrefService(managed_platform, managed_cloud, extension_prefs, command_line, user, recommended_platform, - recommended_cloud, default_pref_store, delegate); + recommended_cloud, default_pref_store); } PrefService* PrefService::CreateIncognitoPrefService( @@ -144,11 +136,9 @@ PrefService::PrefService(PrefStore* managed_platform_prefs, PersistentPrefStore* user_prefs, PrefStore* recommended_platform_prefs, PrefStore* recommended_cloud_prefs, - DefaultPrefStore* default_store, - PrefService::Delegate* delegate) + DefaultPrefStore* default_store) : user_pref_store_(user_prefs), - default_store_(default_store), - delegate_(delegate) { + default_store_(default_store) { pref_notifier_.reset(new PrefNotifierImpl(this)); pref_value_store_.reset( new PrefValueStore(managed_platform_prefs, @@ -167,8 +157,7 @@ PrefService::PrefService(const PrefService& original, PrefStore* incognito_extension_prefs) : user_pref_store_( new OverlayPersistentPrefStore(original.user_pref_store_.get())), - default_store_(original.default_store_.get()), - delegate_(NULL) { + default_store_(original.default_store_.get()){ pref_notifier_.reset(new PrefNotifierImpl(this)); pref_value_store_.reset(original.pref_value_store_->CloneAndSpecialize( NULL, // managed_platform_prefs @@ -194,48 +183,27 @@ PrefService::~PrefService() { default_store_ = NULL; } -void PrefService::OnPrefsRead(PersistentPrefStore::PrefReadError error, - bool no_dir) { - if (no_dir) { - // Bad news. When profile is created, the process that creates the directory - // is explicitly started. So if directory is missing it probably means that - // Chromium hasn't sufficient privileges. - CHECK(delegate_); - delegate_->OnPrefsLoaded(this, false); +void PrefService::InitFromStorage() { + const PersistentPrefStore::PrefReadError error = + user_pref_store_->ReadPrefs(); + if (error == PersistentPrefStore::PREF_READ_ERROR_NONE) return; - } - - if (error != PersistentPrefStore::PREF_READ_ERROR_NONE) { - // Failing to load prefs on startup is a bad thing(TM). See bug 38352 for - // an example problem that this can cause. - // Do some diagnosis and try to avoid losing data. - int message_id = 0; - if (error <= PersistentPrefStore::PREF_READ_ERROR_JSON_TYPE) { - message_id = IDS_PREFERENCES_CORRUPT_ERROR; - } else if (error != PersistentPrefStore::PREF_READ_ERROR_NO_FILE) { - message_id = IDS_PREFERENCES_UNREADABLE_ERROR; - } - if (message_id) { - BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, - NewRunnableFunction(&NotifyReadError, this, message_id)); - } - UMA_HISTOGRAM_ENUMERATION("PrefService.ReadError", error, 20); + // Failing to load prefs on startup is a bad thing(TM). See bug 38352 for + // an example problem that this can cause. + // Do some diagnosis and try to avoid losing data. + int message_id = 0; + if (error <= PersistentPrefStore::PREF_READ_ERROR_JSON_TYPE) { + message_id = IDS_PREFERENCES_CORRUPT_ERROR; + } else if (error != PersistentPrefStore::PREF_READ_ERROR_NO_FILE) { + message_id = IDS_PREFERENCES_UNREADABLE_ERROR; } - if (delegate_) - delegate_->OnPrefsLoaded(this, true); -} - -void PrefService::InitFromStorage() { - if (!delegate_) { - const PersistentPrefStore::PrefReadError error = - user_pref_store_->ReadPrefs(); - OnPrefsRead(error, false); - } else { - // todo(altimofeev): move this method to PersistentPrefStore interface. - (static_cast<JsonPrefStore*>(user_pref_store_.get()))->ReadPrefs(this); + if (message_id) { + BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, + NewRunnableFunction(&NotifyReadError, this, message_id)); } + UMA_HISTOGRAM_ENUMERATION("PrefService.ReadError", error, 20); } bool PrefService::ReloadPersistentPrefs() { diff --git a/chrome/browser/prefs/pref_service.h b/chrome/browser/prefs/pref_service.h index 59e4b51..690b8c2 100644 --- a/chrome/browser/prefs/pref_service.h +++ b/chrome/browser/prefs/pref_service.h @@ -15,7 +15,6 @@ #include "base/memory/scoped_ptr.h" #include "base/threading/non_thread_safe.h" #include "base/values.h" -#include "chrome/common/json_pref_store.h" class DefaultPrefStore; class FilePath; @@ -33,8 +32,7 @@ class PrefMemberBase; class ScopedUserPrefUpdateBase; }; -class PrefService : public base::NonThreadSafe, - public JsonPrefStore::Delegate { +class PrefService : public base::NonThreadSafe { public: // A helper class to store all the information associated with a preference. class Preference { @@ -113,15 +111,6 @@ class PrefService : public base::NonThreadSafe, DISALLOW_COPY_AND_ASSIGN(Preference); }; - class Delegate { - public: - virtual void OnPrefsLoaded(PrefService* prefs, bool success) = 0; - }; - - // JsonPrefStore::Delegate implementaion. - virtual void OnPrefsRead(PersistentPrefStore::PrefReadError error, - bool no_dir); - // Factory method that creates a new instance of a PrefService with the // applicable PrefStores. The |pref_filename| points to the user preference // file. The |profile| is the one to which these preferences apply; it may be @@ -133,12 +122,6 @@ class PrefService : public base::NonThreadSafe, PrefStore* extension_pref_store, Profile* profile); - // Same as above, but with async initialization. - static PrefService* CreatePrefServiceAsync(const FilePath& pref_filename, - PrefStore* extension_pref_store, - Profile* profile, - Delegate* delegate); - // Creates an incognito copy of the pref service that shares most pref stores // but uses a fresh non-persistent overlay for the user pref store and an // individual extension pref store (to cache the effective extension prefs for @@ -255,8 +238,7 @@ class PrefService : public base::NonThreadSafe, PersistentPrefStore* user_prefs, PrefStore* recommended_platform_prefs, PrefStore* recommended_cloud_prefs, - DefaultPrefStore* default_store, - Delegate* delegate); + DefaultPrefStore* default_store); // The PrefNotifier handles registering and notifying preference observers. // It is created and owned by this PrefService. Subclasses may access it for @@ -338,10 +320,6 @@ class PrefService : public base::NonThreadSafe, // of registered preferences are. mutable PreferenceSet prefs_; - // Holds delegator to be called after initialization, if async version - // is used. - Delegate* delegate_; - DISALLOW_COPY_AND_ASSIGN(PrefService); }; diff --git a/chrome/browser/prefs/pref_service_mock_builder.cc b/chrome/browser/prefs/pref_service_mock_builder.cc index 1de0403..14012d1 100644 --- a/chrome/browser/prefs/pref_service_mock_builder.cc +++ b/chrome/browser/prefs/pref_service_mock_builder.cc @@ -113,8 +113,7 @@ PrefService* PrefServiceMockBuilder::Create() { user_prefs_.get(), recommended_platform_prefs_.get(), recommended_cloud_prefs_.get(), - new DefaultPrefStore(), - NULL); + new DefaultPrefStore()); managed_platform_prefs_ = NULL; managed_cloud_prefs_ = NULL; extension_prefs_ = NULL; diff --git a/chrome/browser/profiles/profile.h b/chrome/browser/profiles/profile.h index d63413f..1054aad 100644 --- a/chrome/browser/profiles/profile.h +++ b/chrome/browser/profiles/profile.h @@ -130,12 +130,6 @@ class Profile { IMPLICIT_ACCESS }; - class Delegate { - public: - // Called when creation of the profile is finished. - virtual void OnProfileCreated(Profile* profile, bool success) = 0; - }; - // Key used to bind profile to the widget with which it is associated. static const char* kProfileKey; @@ -152,10 +146,6 @@ class Profile { // Create a new profile given a path. static Profile* CreateProfile(const FilePath& path); - // Same as above, but uses async initialization. - static Profile* CreateProfileAsync(const FilePath& path, - Delegate* delegate); - // Returns the request context for the "default" profile. This may be called // from any thread. This CAN return NULL if a first request context has not // yet been created. If necessary, listen on the UI thread for diff --git a/chrome/browser/profiles/profile_impl.cc b/chrome/browser/profiles/profile_impl.cc index 844642a..66a28b1 100644 --- a/chrome/browser/profiles/profile_impl.cc +++ b/chrome/browser/profiles/profile_impl.cc @@ -231,27 +231,7 @@ void ProfileSizeTask::Run() { // static Profile* Profile::CreateProfile(const FilePath& path) { - if (!file_util::PathExists(path)) { - // TODO(tc): http://b/1094718 Bad things happen if we can't write to the - // profile directory. We should eventually be able to run in this - // situation. - if (!file_util::CreateDirectory(path)) - return NULL; - } - return new ProfileImpl(path, NULL); -} - -// static -Profile* Profile::CreateProfileAsync(const FilePath&path, - Profile::Delegate* delegate) { - DCHECK(delegate); - // This is safe while all file opeartions are done on the FILE thread. - BrowserThread::PostTask(BrowserThread::FILE, - FROM_HERE, - NewRunnableFunction(&file_util::CreateDirectory, - path)); - // Async version. - return new ProfileImpl(path, delegate); + return new ProfileImpl(path); } // static @@ -261,8 +241,7 @@ void ProfileImpl::RegisterUserPrefs(PrefService* prefs) { DefaultApps::RegisterUserPrefs(prefs); } -ProfileImpl::ProfileImpl(const FilePath& path, - Profile::Delegate* delegate) +ProfileImpl::ProfileImpl(const FilePath& path) : path_(path), visited_link_event_listener_(new VisitedLinkEventListener()), extension_devtools_manager_(NULL), @@ -280,31 +259,13 @@ ProfileImpl::ProfileImpl(const FilePath& path, #if defined(OS_WIN) checked_instant_promo_(false), #endif - shutdown_session_service_(false), - delegate_(delegate) { + shutdown_session_service_(false) { DCHECK(!path.empty()) << "Using an empty path will attempt to write " << "profile files to the root directory!"; create_session_service_timer_.Start( TimeDelta::FromMilliseconds(kCreateSessionServiceDelayMS), this, &ProfileImpl::EnsureSessionServiceCreated); - if (delegate_) { - prefs_.reset(PrefService::CreatePrefServiceAsync( - GetPrefFilePath(), - new ExtensionPrefStore(GetExtensionPrefValueMap(), false), - GetOriginalProfile(), - this)); // Ask to notify us in the end. - } else { - // Load prefs synchronously. - prefs_.reset(PrefService::CreatePrefService( - GetPrefFilePath(), - new ExtensionPrefStore(GetExtensionPrefValueMap(), false), - GetOriginalProfile())); - OnPrefsLoaded(prefs_.get(), true); - } -} - -void ProfileImpl::DoFinalInit() { PrefService* prefs = GetPrefs(); pref_change_registrar_.Init(prefs); pref_change_registrar_.Add(prefs::kSpellCheckDictionary, this); @@ -316,16 +277,7 @@ void ProfileImpl::DoFinalInit() { // the cache directory depends on the profile directory, which isn't available // to PathService. chrome::GetUserCacheDirectory(path_, &base_cache_path_); - if (!delegate_) { - file_util::CreateDirectory(base_cache_path_); - } else { - // Async profile loading is used, so call this on the FILE thread instead. - // It is safe since all other file operations should also be done there. - BrowserThread::PostTask(BrowserThread::FILE, - FROM_HERE, - NewRunnableFunction(&file_util::CreateDirectory, - base_cache_path_)); - } + file_util::CreateDirectory(base_cache_path_); #if !defined(OS_CHROMEOS) // Listen for bookmark model load, to bootstrap the sync service. @@ -392,10 +344,6 @@ void ProfileImpl::DoFinalInit() { // Initialize the ProfilePolicyConnector after |io_data_| since it requires // the URLRequestContextGetter to be initialized. GetPolicyConnector()->Initialize(); - - // Creation has been finished. - if (delegate_) - delegate_->OnProfileCreated(this, true); } void ProfileImpl::InitExtensions() { @@ -794,50 +742,44 @@ net::TransportSecurityState* return transport_security_state_.get(); } -void ProfileImpl::OnPrefsLoaded(PrefService* prefs, bool success) { - DCHECK(prefs == prefs_.get()); +PrefService* ProfileImpl::GetPrefs() { + if (!prefs_.get()) { + prefs_.reset(PrefService::CreatePrefService( + GetPrefFilePath(), + new ExtensionPrefStore(GetExtensionPrefValueMap(), false), + GetOriginalProfile())); - if (!success) { - DCHECK(delegate_); - delegate_->OnProfileCreated(this, false); - return; - } + // The Profile class and ProfileManager class may read some prefs so + // register known prefs as soon as possible. + Profile::RegisterUserPrefs(prefs_.get()); + browser::RegisterUserPrefs(prefs_.get()); + // TODO(mirandac): remove migration code after 6 months (crbug.com/69995). + if (g_browser_process->local_state()) { + browser::MigrateBrowserPrefs(prefs_.get(), + g_browser_process->local_state()); + } - // The Profile class and ProfileManager class may read some prefs so - // register known prefs as soon as possible. - Profile::RegisterUserPrefs(prefs_.get()); - browser::RegisterUserPrefs(prefs_.get()); - // TODO(mirandac): remove migration code after 6 months (crbug.com/69995). - if (g_browser_process->local_state()) { - browser::MigrateBrowserPrefs(prefs_.get(), - g_browser_process->local_state()); + // The last session exited cleanly if there is no pref for + // kSessionExitedCleanly or the value for kSessionExitedCleanly is true. + last_session_exited_cleanly_ = + prefs_->GetBoolean(prefs::kSessionExitedCleanly); + // Mark the session as open. + prefs_->SetBoolean(prefs::kSessionExitedCleanly, false); + // Make sure we save to disk that the session has opened. + prefs_->ScheduleSavePersistentPrefs(); + + // Ensure that preferences set by extensions are restored in the profile + // as early as possible. The constructor takes care of that. + extension_prefs_.reset(new ExtensionPrefs( + prefs_.get(), + GetPath().AppendASCII(ExtensionService::kInstallDirectoryName), + GetExtensionPrefValueMap())); + + DCHECK(!net_pref_observer_.get()); + net_pref_observer_.reset( + new NetPrefObserver(prefs_.get(), GetPrerenderManager())); } - // The last session exited cleanly if there is no pref for - // kSessionExitedCleanly or the value for kSessionExitedCleanly is true. - last_session_exited_cleanly_ = - prefs_->GetBoolean(prefs::kSessionExitedCleanly); - // Mark the session as open. - prefs_->SetBoolean(prefs::kSessionExitedCleanly, false); - // Make sure we save to disk that the session has opened. - prefs_->ScheduleSavePersistentPrefs(); - - // Ensure that preferences set by extensions are restored in the profile - // as early as possible. The constructor takes care of that. - extension_prefs_.reset(new ExtensionPrefs( - prefs_.get(), - GetPath().AppendASCII(ExtensionService::kInstallDirectoryName), - GetExtensionPrefValueMap())); - - DCHECK(!net_pref_observer_.get()); - net_pref_observer_.reset( - new NetPrefObserver(prefs_.get(), GetPrerenderManager())); - - DoFinalInit(); -} - -PrefService* ProfileImpl::GetPrefs() { - DCHECK(prefs_.get()); // Should explicitly be initialized. return prefs_.get(); } diff --git a/chrome/browser/profiles/profile_impl.h b/chrome/browser/profiles/profile_impl.h index 617e3bb..7e7095f 100644 --- a/chrome/browser/profiles/profile_impl.h +++ b/chrome/browser/profiles/profile_impl.h @@ -37,8 +37,7 @@ class NetPrefObserver; // The default profile implementation. class ProfileImpl : public Profile, public SpellCheckHostObserver, - public NotificationObserver, - public PrefService::Delegate { + public NotificationObserver { public: virtual ~ProfileImpl(); @@ -157,15 +156,7 @@ class ProfileImpl : public Profile, private: friend class Profile; - ProfileImpl(const FilePath& path, - Profile::Delegate* delegate); - - // Does final initialization. Should be called after prefs were loaded. - void DoFinalInit(); - - // PrefService::Delegate implementation. Does final prefs initialization and - // calls Init(). - void OnPrefsLoaded(PrefService* prefs, bool success); + explicit ProfileImpl(const FilePath& path); void CreateWebDataService(); FilePath GetPrefFilePath(); @@ -318,8 +309,6 @@ class ProfileImpl : public Profile, scoped_ptr<ChromeURLDataManager> chrome_url_data_manager_; - Profile::Delegate* delegate_; - DISALLOW_COPY_AND_ASSIGN(ProfileImpl); }; diff --git a/chrome/browser/profiles/profile_manager.cc b/chrome/browser/profiles/profile_manager.cc index 0f0576a..b893b25 100644 --- a/chrome/browser/profiles/profile_manager.cc +++ b/chrome/browser/profiles/profile_manager.cc @@ -68,9 +68,8 @@ void ProfileManager::ShutdownSessionServices() { ProfileManager* pm = g_browser_process->profile_manager(); if (!pm) // Is NULL when running unit tests. return; - std::vector<Profile*> profiles(pm->GetLoadedProfiles()); - for (size_t i = 0; i < profiles.size(); ++i) - profiles[i]->ShutdownSessionService(); + for (ProfileManager::const_iterator i = pm->begin(); i != pm->end(); ++i) + (*i)->ShutdownSessionService(); } // static @@ -95,6 +94,11 @@ ProfileManager::~ProfileManager() { ui::SystemMonitor* system_monitor = ui::SystemMonitor::Get(); if (system_monitor) system_monitor->RemoveObserver(this); + + // Destroy all profiles that we're keeping track of. + for (const_iterator i(begin()); i != end(); ++i) + delete *i; + profiles_.clear(); } FilePath ProfileManager::GetDefaultProfileDir( @@ -151,10 +155,10 @@ Profile* ProfileManager::GetDefaultProfile(const FilePath& user_data_dir) { if (!command_line.HasSwitch(switches::kTestType) || command_line.HasSwitch(switches::kLoginProfile)) { // Don't init extensions for this profile - profile = GetProfile(default_profile_dir); + profile = GetProfile(default_profile_dir, false); profile = profile->GetOffTheRecordProfile(); } else { - profile = GetProfile(default_profile_dir); + profile = GetProfile(default_profile_dir, true); } return profile; } @@ -162,102 +166,63 @@ Profile* ProfileManager::GetDefaultProfile(const FilePath& user_data_dir) { return GetProfile(default_profile_dir); } +Profile* ProfileManager::GetProfile(const FilePath& profile_dir) { + return GetProfile(profile_dir, true); +} + Profile* ProfileManager::GetProfileWithId(ProfileId profile_id) { DCHECK_NE(Profile::kInvalidProfileId, profile_id); - for (ProfilesInfoMap::iterator iter = profiles_info_.begin(); - iter != profiles_info_.end(); ++iter) { - if (iter->second->created) { - Profile* candidate = iter->second->profile.get(); - if (candidate->GetRuntimeId() == profile_id) - return candidate; - if (candidate->HasOffTheRecordProfile()) { - candidate = candidate->GetOffTheRecordProfile(); - if (candidate->GetRuntimeId() == profile_id) - return candidate; - } + for (iterator i = begin(); i != end(); ++i) { + if ((*i)->GetRuntimeId() == profile_id) + return *i; + if ((*i)->HasOffTheRecordProfile() && + (*i)->GetOffTheRecordProfile()->GetRuntimeId() == profile_id) { + return (*i)->GetOffTheRecordProfile(); } } return NULL; } bool ProfileManager::IsValidProfile(Profile* profile) { - for (ProfilesInfoMap::iterator iter = profiles_info_.begin(); - iter != profiles_info_.end(); ++iter) { - if (iter->second->created) { - Profile* candidate = iter->second->profile.get(); - if (candidate == profile || - (candidate->HasOffTheRecordProfile() && - candidate->GetOffTheRecordProfile() == profile)) { - return true; - } + for (iterator i = begin(); i != end(); ++i) { + if (*i == profile) + return true; + if ((*i)->HasOffTheRecordProfile() && + (*i)->GetOffTheRecordProfile() == profile) { + return true; } } return false; } -std::vector<Profile*> ProfileManager::GetLoadedProfiles() const { - std::vector<Profile*> profiles; - for (ProfilesInfoMap::const_iterator iter = profiles_info_.begin(); - iter != profiles_info_.end(); ++iter) { - if (iter->second->created) - profiles.push_back(iter->second->profile.get()); - } - return profiles; -} - -Profile* ProfileManager::GetProfile(const FilePath& profile_dir) { +Profile* ProfileManager::GetProfile( + const FilePath& profile_dir, bool init_extensions) { // If the profile is already loaded (e.g., chrome.exe launched twice), just // return it. Profile* profile = GetProfileByPath(profile_dir); if (NULL != profile) return profile; - profile = Profile::CreateProfile(profile_dir); + if (!ProfileManager::IsProfile(profile_dir)) { + // If the profile directory doesn't exist, create it. + profile = ProfileManager::CreateProfile(profile_dir); + } else { + // The profile already exists on disk, just load it. + profile = Profile::CreateProfile(profile_dir); + } DCHECK(profile); if (profile) { - bool result = AddProfile(profile); + bool result = AddProfile(profile, init_extensions); DCHECK(result); } return profile; } -void ProfileManager::CreateProfileAsync(const FilePath& user_data_dir, - Observer* observer) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - ProfilesInfoMap::iterator iter = profiles_info_.find(user_data_dir); - if (iter != profiles_info_.end()) { - ProfileInfo* info = iter->second.get(); - if (info->created) { - // Profile has already been created. Call observer immediately. - observer->OnProfileCreated(info->profile.get()); - } else { - // Profile is being created. Add observer to list. - info->observers.push_back(observer); - } - } else { - // Initiate asynchronous creation process. - ProfileInfo* info = - RegisterProfile(Profile::CreateProfileAsync(user_data_dir, this), - false); - info->observers.push_back(observer); - } -} - -// static -void ProfileManager::CreateDefaultProfileAsync(Observer* observer) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - ProfileManager* profile_manager = g_browser_process->profile_manager(); - - FilePath default_profile_dir; - PathService::Get(chrome::DIR_USER_DATA, &default_profile_dir); - default_profile_dir = default_profile_dir.Append( - profile_manager->GetCurrentProfileDir()); - - profile_manager->CreateProfileAsync(default_profile_dir, - observer); +void ProfileManager::RegisterProfile(Profile* profile) { + profiles_.insert(profiles_.end(), profile); } -bool ProfileManager::AddProfile(Profile* profile) { +bool ProfileManager::AddProfile(Profile* profile, bool init_extensions) { DCHECK(profile); // Make sure that we're not loading a profile with the same ID as a profile @@ -269,22 +234,22 @@ bool ProfileManager::AddProfile(Profile* profile) { return false; } - RegisterProfile(profile, true); - DoFinalInit(profile); + profiles_.insert(profiles_.end(), profile); + if (init_extensions) + profile->InitExtensions(); + const CommandLine& command_line = *CommandLine::ForCurrentProcess(); + if (!command_line.HasSwitch(switches::kDisableWebResources)) + profile->InitPromoResources(); return true; } -ProfileManager::ProfileInfo* ProfileManager::RegisterProfile(Profile* profile, - bool created) { - ProfileInfo* info = new ProfileInfo(profile, created); - ProfilesInfoMap::iterator new_elem = - (profiles_info_.insert(std::make_pair(profile->GetPath(), info))).first; - return info; -} - Profile* ProfileManager::GetProfileByPath(const FilePath& path) const { - ProfilesInfoMap::const_iterator iter = profiles_info_.find(path); - return (iter == profiles_info_.end()) ? NULL : iter->second->profile.get(); + for (const_iterator i(begin()); i != end(); ++i) { + if ((*i)->GetPath() == path) + return *i; + } + + return NULL; } void ProfileManager::OnSuspend() { @@ -296,14 +261,13 @@ void ProfileManager::OnSuspend() { DCHECK(posted); scoped_refptr<net::URLRequestContextGetter> request_context; - std::vector<Profile*> profiles(GetLoadedProfiles()); - for (size_t i = 0; i < profiles.size(); ++i) { - request_context = profiles[i]->GetRequestContext(); + for (const_iterator i(begin()); i != end(); ++i) { + request_context = (*i)->GetRequestContext(); posted = BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, NewRunnableFunction(&SuspendRequestContext, request_context)); DCHECK(posted); - request_context = profiles[i]->GetRequestContextForMedia(); + request_context = (*i)->GetRequestContextForMedia(); posted = BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, NewRunnableFunction(&SuspendRequestContext, request_context)); @@ -315,14 +279,13 @@ void ProfileManager::OnResume() { DCHECK(CalledOnValidThread()); scoped_refptr<net::URLRequestContextGetter> request_context; - std::vector<Profile*> profiles(GetLoadedProfiles()); - for (size_t i = 0; i < profiles.size(); ++i) { - request_context = profiles[i]->GetRequestContext(); + for (const_iterator i(begin()); i != end(); ++i) { + request_context = (*i)->GetRequestContext(); bool posted = BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, NewRunnableFunction(&ResumeRequestContext, request_context)); DCHECK(posted); - request_context = profiles[i]->GetRequestContextForMedia(); + request_context = (*i)->GetRequestContextForMedia(); posted = BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, NewRunnableFunction(&ResumeRequestContext, request_context)); @@ -352,50 +315,30 @@ void ProfileManager::Observe( #endif } -void ProfileManager::DoFinalInit(Profile* profile) { - const CommandLine& command_line = *CommandLine::ForCurrentProcess(); - bool init_extensions = true; -#if defined(OS_CHROMEOS) - if (!logged_in_ && - (!command_line.HasSwitch(switches::kTestType) || - command_line.HasSwitch(switches::kLoginProfile))) { - init_extensions = false; - } -#endif - if (init_extensions) - profile->InitExtensions(); +// static +bool ProfileManager::IsProfile(const FilePath& path) { + FilePath prefs_path = GetProfilePrefsPath(path); + FilePath history_path = path; + history_path = history_path.Append(chrome::kHistoryFilename); - if (!command_line.HasSwitch(switches::kDisableWebResources)) - profile->InitPromoResources(); + return file_util::PathExists(prefs_path) && + file_util::PathExists(history_path); } -void ProfileManager::OnProfileCreated(Profile* profile, bool success) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - - ProfilesInfoMap::iterator iter = profiles_info_.find(profile->GetPath()); - DCHECK(iter != profiles_info_.end()); - ProfileInfo* info = iter->second.get(); - - std::vector<Observer*> observers; - info->observers.swap(observers); - - if (success) { - DoFinalInit(profile); - info->created = true; -#if defined(OS_CHROMEOS) - const CommandLine& command_line = *CommandLine::ForCurrentProcess(); - if (!logged_in_ && - (!command_line.HasSwitch(switches::kTestType) || - command_line.HasSwitch(switches::kLoginProfile))) { - profile = profile->GetOffTheRecordProfile(); - } -#endif - } else { - profile = NULL; - profiles_info_.erase(iter); +// static +Profile* ProfileManager::CreateProfile(const FilePath& path) { + if (IsProfile(path)) { + DCHECK(false) << "Attempted to create a profile with the path:\n" + << path.value() << "\n but that path already contains a profile"; } - for (size_t i = 0; i < observers.size(); ++i) { - observers[i]->OnProfileCreated(profile); + if (!file_util::PathExists(path)) { + // TODO(tc): http://b/1094718 Bad things happen if we can't write to the + // profile directory. We should eventually be able to run in this + // situation. + if (!file_util::CreateDirectory(path)) + return NULL; } + + return Profile::CreateProfile(path); } diff --git a/chrome/browser/profiles/profile_manager.h b/chrome/browser/profiles/profile_manager.h index eeca447..c90834f 100644 --- a/chrome/browser/profiles/profile_manager.h +++ b/chrome/browser/profiles/profile_manager.h @@ -11,10 +11,6 @@ #include <vector> #include "base/basictypes.h" -#include "base/file_path.h" -#include "base/hash_tables.h" -#include "base/memory/linked_ptr.h" -#include "base/memory/scoped_ptr.h" #include "base/message_loop.h" #include "base/threading/non_thread_safe.h" #include "chrome/browser/profiles/profile.h" @@ -26,16 +22,8 @@ class FilePath; class ProfileManager : public base::NonThreadSafe, public ui::SystemMonitor::PowerObserver, - public NotificationObserver, - public Profile::Delegate { + public NotificationObserver { public: - class Observer { - public: - // This method is called when profile is ready. If profile creation has been - // failed, method is called with |profile| equals to NULL. - virtual void OnProfileCreated(Profile* profile) = 0; - }; - ProfileManager(); virtual ~ProfileManager(); @@ -56,16 +44,6 @@ class ProfileManager : public base::NonThreadSafe, // otherwise it will create and manage it. Profile* GetProfile(const FilePath& profile_dir); - // Explicit asynchronous creation of the profile. |observer| is called - // when profile is created. If profile has already been created, observer - // is called immediately. Should be called on the UI thread. - void CreateProfileAsync(const FilePath& user_data_dir, - Observer* observer); - - // Initiates default profile creation. If default profile has already been - // created, observer is called immediately. Should be called on the UI thread. - static void CreateDefaultProfileAsync(Observer* observer); - // Returns the profile with the given |profile_id| or NULL if no such profile // exists. Profile* GetProfileWithId(ProfileId profile_id); @@ -74,13 +52,28 @@ class ProfileManager : public base::NonThreadSafe, // profile. bool IsValidProfile(Profile* profile); + // Returns a profile for a specific profile directory within the user data + // dir with the option of controlling whether extensions are initialized + // or not. This will return an existing profile it had already been created, + // otherwise it will create and manage it. + // Note that if the profile has already been created, extensions may have + // been initialized. If this matters to you, you should call GetProfileByPath + // first to see if the profile already exists. + Profile* GetProfile(const FilePath& profile_dir, bool init_extensions); + // Returns the directory where the currently active profile is // stored, relative to the user data directory currently in use.. FilePath GetCurrentProfileDir(); - // Returns created profiles. Note, profiles order is NOT guaranteed to be - // related with the creation order. - std::vector<Profile*> GetLoadedProfiles() const; + // These allow iteration through the current list of profiles. + typedef std::vector<Profile*> ProfileVector; + typedef ProfileVector::iterator iterator; + typedef ProfileVector::const_iterator const_iterator; + + iterator begin() { return profiles_.begin(); } + const_iterator begin() const { return profiles_.begin(); } + iterator end() { return profiles_.end(); } + const_iterator end() const { return profiles_.end(); } // PowerObserver notifications virtual void OnSuspend(); @@ -100,48 +93,35 @@ class ProfileManager : public base::NonThreadSafe, // Returns the path to the preferences file given the user profile directory. static FilePath GetProfilePrefsPath(const FilePath& profile_dir); + // Tries to determine whether the given path represents a profile + // directory, and returns true if it thinks it does. + static bool IsProfile(const FilePath& path); + // If a profile with the given path is currently managed by this object, // return a pointer to the corresponding Profile object; // otherwise return NULL. Profile* GetProfileByPath(const FilePath& path) const; - // Profile::Delegate implementation: - virtual void OnProfileCreated(Profile* profile, bool success); - - protected: - // Does final initial actions. - virtual void DoFinalInit(Profile* profile); + // Creates a new profile at the specified path. + // This method should always return a valid Profile (i.e., should never + // return NULL). + static Profile* CreateProfile(const FilePath& path); private: friend class ExtensionEventRouterForwarderTest; - // This struct contains information about profiles which are being loaded or - // were loaded. - struct ProfileInfo { - ProfileInfo(Profile* profile, bool created) - : profile(profile), created(created) { - } - - scoped_ptr<Profile> profile; - // Whether profile has been fully loaded (created and initialized). - bool created; - // List of observers which should be notified when profile initialization is - // done. Note, when profile is fully loaded this vector will be empty. - std::vector<Observer*> observers; - - private: - DISALLOW_COPY_AND_ASSIGN(ProfileInfo); - }; + // Helper method for unit tests to inject |profile| into the ProfileManager. + void RegisterProfile(Profile* profile); // Adds a pre-existing Profile object to the set managed by this // ProfileManager. This ProfileManager takes ownership of the Profile. // The Profile should not already be managed by this ProfileManager. // Returns true if the profile was added, false otherwise. - bool AddProfile(Profile* profile); + bool AddProfile(Profile* profile, bool init_extensions); - // Registers profile with given info. Returns pointer to created ProfileInfo - // entry. - ProfileInfo* RegisterProfile(Profile* profile, bool created); + // We keep a simple vector of profiles rather than something fancier + // because we expect there to be a small number of profiles active. + ProfileVector profiles_; NotificationRegistrar registrar_; @@ -150,19 +130,7 @@ class ProfileManager : public base::NonThreadSafe, // default. bool logged_in_; - // Maps profile path to ProfileInfo (if profile has been created). Use - // RegisterProfile() to add into this map. - typedef std::map<FilePath, linked_ptr<ProfileInfo> > ProfilesInfoMap; - ProfilesInfoMap profiles_info_; - DISALLOW_COPY_AND_ASSIGN(ProfileManager); }; -// Same as the ProfileManager, but doesn't initialize some services of the -// profile. This one is useful in unittests. -class ProfileManagerWithoutInit : public ProfileManager { - protected: - virtual void DoFinalInit(Profile*) {} -}; - #endif // CHROME_BROWSER_PROFILES_PROFILE_MANAGER_H_ diff --git a/chrome/browser/profiles/profile_manager_unittest.cc b/chrome/browser/profiles/profile_manager_unittest.cc index 7080055..eeea273 100644 --- a/chrome/browser/profiles/profile_manager_unittest.cc +++ b/chrome/browser/profiles/profile_manager_unittest.cc @@ -18,23 +18,14 @@ #include "chrome/test/testing_pref_service.h" #include "content/browser/browser_thread.h" #include "content/common/notification_service.h" -#include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/base/system_monitor/system_monitor.h" -namespace { -// This global variable is used to check that value returned to different -// observers is the same. -Profile* g_created_profile; - -} // namespace - class ProfileManagerTest : public testing::Test { protected: ProfileManagerTest() : ui_thread_(BrowserThread::UI, &message_loop_), - file_thread_(BrowserThread::FILE, &message_loop_), - profile_manager_(new ProfileManagerWithoutInit) { + file_thread_(BrowserThread::FILE, &message_loop_) { } virtual void SetUp() { @@ -49,18 +40,11 @@ class ProfileManagerTest : public testing::Test { } virtual void TearDown() { - profile_manager_.reset(); - TestingBrowserProcess* testing_browser_process = static_cast<TestingBrowserProcess*>(g_browser_process); testing_browser_process->SetPrefService(NULL); } - class MockObserver : public ProfileManager::Observer { - public: - MOCK_METHOD1(OnProfileCreated, void(Profile* profile)); - }; - // The path to temporary directory used to contain the test operations. ScopedTempDir temp_dir_; @@ -68,30 +52,40 @@ class ProfileManagerTest : public testing::Test { BrowserThread ui_thread_; BrowserThread file_thread_; - ui::SystemMonitor system_monitor_dummy_; - - // Also will test profile deletion. - scoped_ptr<ProfileManager> profile_manager_; - TestingPrefService test_local_state_; }; -TEST_F(ProfileManagerTest, GetProfile) { +TEST_F(ProfileManagerTest, CreateProfile) { + FilePath source_path; + PathService::Get(chrome::DIR_TEST_DATA, &source_path); + source_path = source_path.Append(FILE_PATH_LITERAL("profiles")); + source_path = source_path.Append(FILE_PATH_LITERAL("sample")); + FilePath dest_path = temp_dir_.path(); dest_path = dest_path.Append(FILE_PATH_LITERAL("New Profile")); - Profile* profile; + scoped_ptr<Profile> profile; // Successfully create a profile. - profile = profile_manager_->GetProfile(dest_path); - EXPECT_TRUE(profile); + profile.reset(ProfileManager::CreateProfile(dest_path)); + ASSERT_TRUE(profile.get()); + + profile.reset(); - // The profile already exists when we call GetProfile. Just load it. - EXPECT_EQ(profile, profile_manager_->GetProfile(dest_path)); +#ifdef NDEBUG + // In Release mode, we always try to always return a profile. In debug, + // these cases would trigger DCHECKs. + + // The profile already exists when we call CreateProfile. Just load it. + profile.reset(ProfileManager::CreateProfile(dest_path)); + ASSERT_TRUE(profile.get()); +#endif } TEST_F(ProfileManagerTest, DefaultProfileDir) { CommandLine *cl = CommandLine::ForCurrentProcess(); + ui::SystemMonitor dummy; + ProfileManager profile_manager; std::string profile_dir("my_user"); cl->AppendSwitch(switches::kTestType); @@ -99,13 +93,15 @@ TEST_F(ProfileManagerTest, DefaultProfileDir) { FilePath expected_default = FilePath().AppendASCII(chrome::kNotSignedInProfile); EXPECT_EQ(expected_default.value(), - profile_manager_->GetCurrentProfileDir().value()); + profile_manager.GetCurrentProfileDir().value()); } #if defined(OS_CHROMEOS) // This functionality only exists on Chrome OS. TEST_F(ProfileManagerTest, LoggedInProfileDir) { CommandLine *cl = CommandLine::ForCurrentProcess(); + ui::SystemMonitor dummy; + ProfileManager profile_manager; std::string profile_dir("my_user"); cl->AppendSwitchASCII(switches::kLoginProfile, profile_dir); @@ -114,36 +110,41 @@ TEST_F(ProfileManagerTest, LoggedInProfileDir) { FilePath expected_default = FilePath().AppendASCII(chrome::kNotSignedInProfile); EXPECT_EQ(expected_default.value(), - profile_manager_->GetCurrentProfileDir().value()); + profile_manager.GetCurrentProfileDir().value()); - profile_manager_->Observe(NotificationType::LOGIN_USER_CHANGED, - NotificationService::AllSources(), - NotificationService::NoDetails()); + profile_manager.Observe(NotificationType::LOGIN_USER_CHANGED, + NotificationService::AllSources(), + NotificationService::NoDetails()); FilePath expected_logged_in(profile_dir); EXPECT_EQ(expected_logged_in.value(), - profile_manager_->GetCurrentProfileDir().value()); + profile_manager.GetCurrentProfileDir().value()); VLOG(1) << temp_dir_.path().Append( - profile_manager_->GetCurrentProfileDir()).value(); + profile_manager.GetCurrentProfileDir()).value(); } #endif TEST_F(ProfileManagerTest, CreateAndUseTwoProfiles) { + FilePath source_path; + PathService::Get(chrome::DIR_TEST_DATA, &source_path); + source_path = source_path.Append(FILE_PATH_LITERAL("profiles")); + source_path = source_path.Append(FILE_PATH_LITERAL("sample")); + FilePath dest_path1 = temp_dir_.path(); dest_path1 = dest_path1.Append(FILE_PATH_LITERAL("New Profile 1")); FilePath dest_path2 = temp_dir_.path(); dest_path2 = dest_path2.Append(FILE_PATH_LITERAL("New Profile 2")); - Profile* profile1; - Profile* profile2; + scoped_ptr<Profile> profile1; + scoped_ptr<Profile> profile2; // Successfully create the profiles. - profile1 = profile_manager_->GetProfile(dest_path1); - ASSERT_TRUE(profile1); + profile1.reset(ProfileManager::CreateProfile(dest_path1)); + ASSERT_TRUE(profile1.get()); - profile2 = profile_manager_->GetProfile(dest_path2); - ASSERT_TRUE(profile2); + profile2.reset(ProfileManager::CreateProfile(dest_path2)); + ASSERT_TRUE(profile2.get()); // Force lazy-init of some profile services to simulate use. EXPECT_TRUE(profile1->GetHistoryService(Profile::EXPLICIT_ACCESS)); @@ -154,62 +155,9 @@ TEST_F(ProfileManagerTest, CreateAndUseTwoProfiles) { // Make sure any pending tasks run before we destroy the profiles. message_loop_.RunAllPending(); - profile_manager_.reset(); + profile1.reset(); + profile2.reset(); // Make sure history cleans up correctly. message_loop_.RunAllPending(); } - -// Tests asynchronous profile creation mechanism. -TEST_F(ProfileManagerTest, CreateProfileAsync) { - FilePath dest_path = - temp_dir_.path().Append(FILE_PATH_LITERAL("New Profile")); - - MockObserver mock_observer; - EXPECT_CALL(mock_observer, OnProfileCreated(testing::NotNull())).Times(1); - - profile_manager_->CreateProfileAsync(dest_path, &mock_observer); - - message_loop_.RunAllPending(); -} - -MATCHER(SameNotNull, "The same non-NULL value for all cals.") { - if (!g_created_profile) - g_created_profile = arg; - return g_created_profile == arg; -} - -TEST_F(ProfileManagerTest, CreateProfileAsyncMultipleRequests) { - FilePath dest_path = - temp_dir_.path().Append(FILE_PATH_LITERAL("New Profile")); - - g_created_profile = NULL; - - MockObserver mock_observer1; - EXPECT_CALL(mock_observer1, OnProfileCreated(SameNotNull())).Times(1); - MockObserver mock_observer2; - EXPECT_CALL(mock_observer2, OnProfileCreated(SameNotNull())).Times(1); - MockObserver mock_observer3; - EXPECT_CALL(mock_observer3, OnProfileCreated(SameNotNull())).Times(1); - - profile_manager_->CreateProfileAsync(dest_path, &mock_observer1); - profile_manager_->CreateProfileAsync(dest_path, &mock_observer2); - profile_manager_->CreateProfileAsync(dest_path, &mock_observer3); - - message_loop_.RunAllPending(); -} - -TEST_F(ProfileManagerTest, CreateProfilesAsync) { - FilePath dest_path1 = - temp_dir_.path().Append(FILE_PATH_LITERAL("New Profile 1")); - FilePath dest_path2 = - temp_dir_.path().Append(FILE_PATH_LITERAL("New Profile 2")); - - MockObserver mock_observer; - EXPECT_CALL(mock_observer, OnProfileCreated(testing::NotNull())).Times(2); - - profile_manager_->CreateProfileAsync(dest_path1, &mock_observer); - profile_manager_->CreateProfileAsync(dest_path2, &mock_observer); - - message_loop_.RunAllPending(); -} diff --git a/chrome/browser/task_manager/task_manager.cc b/chrome/browser/task_manager/task_manager.cc index 746c07a..7f8a5d3 100644 --- a/chrome/browser/task_manager/task_manager.cc +++ b/chrome/browser/task_manager/task_manager.cc @@ -979,13 +979,12 @@ void TaskManager::OpenAboutMemory() { if (!browser) { // On OS X, the task manager can be open without any open browser windows. - if (!g_browser_process || !g_browser_process->profile_manager()) + if (!g_browser_process || + !g_browser_process->profile_manager() || + g_browser_process->profile_manager()->begin() == + g_browser_process->profile_manager()->end()) return; - Profile* profile = - g_browser_process->profile_manager()->GetDefaultProfile(); - if (!profile) - return; - browser = Browser::Create(profile); + browser = Browser::Create(*g_browser_process->profile_manager()->begin()); browser->OpenURL(GURL(chrome::kAboutMemoryURL), GURL(), NEW_FOREGROUND_TAB, PageTransition::LINK); browser->window()->Show(); diff --git a/chrome/browser/task_manager/task_manager_resource_providers.cc b/chrome/browser/task_manager/task_manager_resource_providers.cc index 05d17b8..c4dfbf8 100644 --- a/chrome/browser/task_manager/task_manager_resource_providers.cc +++ b/chrome/browser/task_manager/task_manager_resource_providers.cc @@ -681,11 +681,11 @@ void TaskManagerBackgroundContentsResourceProvider::StartUpdating() { // Add all the existing BackgroundContents from every profile. ProfileManager* profile_manager = g_browser_process->profile_manager(); - std::vector<Profile*> profiles(profile_manager->GetLoadedProfiles()); - for (size_t i = 0; i < profiles.size(); ++i) { + for (ProfileManager::const_iterator it = profile_manager->begin(); + it != profile_manager->end(); ++it) { BackgroundContentsService* background_contents_service = - profiles[i]->GetBackgroundContentsService(); - ExtensionService* extensions_service = profiles[i]->GetExtensionService(); + (*it)->GetBackgroundContentsService(); + ExtensionService* extensions_service = (*it)->GetExtensionService(); std::vector<BackgroundContents*> contents = background_contents_service->GetBackgroundContents(); for (std::vector<BackgroundContents*>::iterator iterator = contents.begin(); @@ -1207,10 +1207,10 @@ void TaskManagerExtensionProcessResourceProvider::StartUpdating() { // Add all the existing ExtensionHosts. ProfileManager* profile_manager = g_browser_process->profile_manager(); - std::vector<Profile*> profiles(profile_manager->GetLoadedProfiles()); - for (size_t i = 0; i < profiles.size(); ++i) { + for (ProfileManager::const_iterator it = profile_manager->begin(); + it != profile_manager->end(); ++it) { ExtensionProcessManager* process_manager = - profiles[i]->GetExtensionProcessManager(); + (*it)->GetExtensionProcessManager(); if (process_manager) { ExtensionProcessManager::const_iterator jt; for (jt = process_manager->begin(); jt != process_manager->end(); ++jt) @@ -1221,7 +1221,7 @@ void TaskManagerExtensionProcessResourceProvider::StartUpdating() { // extensions. if (BrowserList::IsOffTheRecordSessionActive()) { ExtensionProcessManager* process_manager = - profiles[i]->GetOffTheRecordProfile()->GetExtensionProcessManager(); + (*it)->GetOffTheRecordProfile()->GetExtensionProcessManager(); if (process_manager) { ExtensionProcessManager::const_iterator jt; for (jt = process_manager->begin(); jt != process_manager->end(); ++jt) diff --git a/chrome/common/json_pref_store.cc b/chrome/common/json_pref_store.cc index 3726c10..b8d323b 100644 --- a/chrome/common/json_pref_store.cc +++ b/chrome/common/json_pref_store.cc @@ -6,123 +6,15 @@ #include <algorithm> -#include "base/bind.h" -#include "base/callback.h" #include "base/file_util.h" -#include "base/memory/ref_counted.h" #include "base/values.h" #include "chrome/common/json_value_serializer.h" -#include "content/browser/browser_thread.h" namespace { // Some extensions we'll tack on to copies of the Preferences files. const FilePath::CharType* kBadExtension = FILE_PATH_LITERAL("bad"); -// Differentiates file loading between UI and FILE threads. -class FileThreadDeserializer - : public base::RefCountedThreadSafe<FileThreadDeserializer> { - public: - explicit FileThreadDeserializer(JsonPrefStore* delegate) - : delegate_(delegate) { - } - - void Start(const FilePath& path) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - BrowserThread::PostTask( - BrowserThread::FILE, - FROM_HERE, - NewRunnableMethod(this, - &FileThreadDeserializer::ReadFileAndReport, - path)); - } - - // Deserializes JSON on the FILE thread. - void ReadFileAndReport(const FilePath& path) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); - - int error_code; - std::string error_msg; - JSONFileValueSerializer serializer(path); - value_.reset(serializer.Deserialize(&error_code, &error_msg)); - - HandleErrors(value_.get(), path, error_code, error_msg, &error_); - - no_dir_ = !file_util::PathExists(path.DirName()); - - BrowserThread::PostTask( - BrowserThread::UI, - FROM_HERE, - NewRunnableMethod(this, &FileThreadDeserializer::ReportOnUIThread)); - } - - // Reports deserialization result on the UI thread. - void ReportOnUIThread() { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - delegate_->OnFileRead(value_.release(), error_, no_dir_); - } - - static void HandleErrors(const Value* value, - const FilePath& path, - int error_code, - const std::string& error_msg, - PersistentPrefStore::PrefReadError* error); - - private: - friend class base::RefCountedThreadSafe<FileThreadDeserializer>; - - bool no_dir_; - PersistentPrefStore::PrefReadError error_; - scoped_ptr<Value> value_; - scoped_refptr<JsonPrefStore> delegate_; -}; - -// static -void FileThreadDeserializer::HandleErrors( - const Value* value, - const FilePath& path, - int error_code, - const std::string& error_msg, - PersistentPrefStore::PrefReadError* error) { - *error = PersistentPrefStore::PREF_READ_ERROR_NONE; - if (!value) { - DLOG(ERROR) << "Error while loading JSON file: " << error_msg; - switch (error_code) { - case JSONFileValueSerializer::JSON_ACCESS_DENIED: - *error = PersistentPrefStore::PREF_READ_ERROR_ACCESS_DENIED; - break; - case JSONFileValueSerializer::JSON_CANNOT_READ_FILE: - *error = PersistentPrefStore::PREF_READ_ERROR_FILE_OTHER; - break; - case JSONFileValueSerializer::JSON_FILE_LOCKED: - *error = PersistentPrefStore::PREF_READ_ERROR_FILE_LOCKED; - break; - case JSONFileValueSerializer::JSON_NO_SUCH_FILE: - *error = PersistentPrefStore::PREF_READ_ERROR_NO_FILE; - break; - default: - *error = PersistentPrefStore::PREF_READ_ERROR_JSON_PARSE; - // JSON errors indicate file corruption of some sort. - // Since the file is corrupt, move it to the side and continue with - // empty preferences. This will result in them losing their settings. - // We keep the old file for possible support and debugging assistance - // as well as to detect if they're seeing these errors repeatedly. - // TODO(erikkay) Instead, use the last known good file. - FilePath bad = path.ReplaceExtension(kBadExtension); - - // If they've ever had a parse error before, put them in another bucket. - // TODO(erikkay) if we keep this error checking for very long, we may - // want to differentiate between recent and long ago errors. - if (file_util::PathExists(bad)) - *error = PersistentPrefStore::PREF_READ_ERROR_JSON_REPEAT; - file_util::Move(path, bad); - break; - } - } else if (!value->IsType(Value::TYPE_DICTIONARY)) { - *error = PersistentPrefStore::PREF_READ_ERROR_JSON_TYPE; - } -} - } // namespace JsonPrefStore::JsonPrefStore(const FilePath& filename, @@ -190,80 +82,70 @@ bool JsonPrefStore::ReadOnly() const { return read_only_; } -void JsonPrefStore::OnFileRead(Value* value_owned, - PersistentPrefStore::PrefReadError error, - bool no_dir) { - scoped_ptr<Value> value(value_owned); - switch (error) { - case PREF_READ_ERROR_ACCESS_DENIED: - case PREF_READ_ERROR_FILE_OTHER: - case PREF_READ_ERROR_FILE_LOCKED: - case PREF_READ_ERROR_JSON_TYPE: - read_only_ = true; - break; - case PREF_READ_ERROR_NONE: - DCHECK(value.get()); - prefs_.reset(static_cast<DictionaryValue*>(value.release())); - break; - case PREF_READ_ERROR_NO_FILE: - // If the file just doesn't exist, maybe this is first run. In any case - // there's no harm in writing out default prefs in this case. - break; - case PREF_READ_ERROR_JSON_PARSE: - case PREF_READ_ERROR_JSON_REPEAT: - break; - default: - NOTREACHED() << "Unknown error: " << error; - } - - if (delegate_) - delegate_->OnPrefsRead(error, no_dir); -} - -void JsonPrefStore::ReadPrefs(Delegate* delegate) { - DCHECK(delegate); - delegate_ = delegate; - - if (path_.empty()) { - read_only_ = true; - delegate_->OnPrefsRead(PREF_READ_ERROR_FILE_NOT_SPECIFIED, false); - return; - } - - // This guarantees that class will not be deleted while JSON is readed. - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - - // Start async reading of the preferences file. It will delete itself - // in the end. - scoped_refptr<FileThreadDeserializer> deserializer( - new FileThreadDeserializer(this)); - deserializer->Start(path_); -} - PersistentPrefStore::PrefReadError JsonPrefStore::ReadPrefs() { - delegate_ = NULL; - if (path_.empty()) { read_only_ = true; return PREF_READ_ERROR_FILE_NOT_SPECIFIED; } + JSONFileValueSerializer serializer(path_); int error_code = 0; std::string error_msg; - - JSONFileValueSerializer serializer(path_); scoped_ptr<Value> value(serializer.Deserialize(&error_code, &error_msg)); + if (!value.get()) { + PrefReadError error; + switch (error_code) { + case JSONFileValueSerializer::JSON_ACCESS_DENIED: + // If the file exists but is simply unreadable, put the file into a + // state where we don't try to save changes. Otherwise, we could + // clobber the existing prefs. + error = PREF_READ_ERROR_ACCESS_DENIED; + read_only_ = true; + break; + case JSONFileValueSerializer::JSON_CANNOT_READ_FILE: + error = PREF_READ_ERROR_FILE_OTHER; + read_only_ = true; + break; + case JSONFileValueSerializer::JSON_FILE_LOCKED: + error = PREF_READ_ERROR_FILE_LOCKED; + read_only_ = true; + break; + case JSONFileValueSerializer::JSON_NO_SUCH_FILE: + // If the file just doesn't exist, maybe this is first run. In any case + // there's no harm in writing out default prefs in this case. + error = PREF_READ_ERROR_NO_FILE; + break; + default: + error = PREF_READ_ERROR_JSON_PARSE; + // JSON errors indicate file corruption of some sort. + // Since the file is corrupt, move it to the side and continue with + // empty preferences. This will result in them losing their settings. + // We keep the old file for possible support and debugging assistance + // as well as to detect if they're seeing these errors repeatedly. + // TODO(erikkay) Instead, use the last known good file. + FilePath bad = path_.ReplaceExtension(kBadExtension); - PersistentPrefStore::PrefReadError error; - FileThreadDeserializer::HandleErrors(value.get(), - path_, - error_code, - error_msg, - &error); + // If they've ever had a parse error before, put them in another bucket. + // TODO(erikkay) if we keep this error checking for very long, we may + // want to differentiate between recent and long ago errors. + if (file_util::PathExists(bad)) + error = PREF_READ_ERROR_JSON_REPEAT; + file_util::Move(path_, bad); + break; + } + return error; + } + + // Preferences should always have a dictionary root. + if (!value->IsType(Value::TYPE_DICTIONARY)) { + // See comment for the default case above. + read_only_ = true; + return PREF_READ_ERROR_JSON_TYPE; + } - OnFileRead(value.release(), error, false); + prefs_.reset(static_cast<DictionaryValue*>(value.release())); - return error; + return PREF_READ_ERROR_NONE; } bool JsonPrefStore::WritePrefs() { diff --git a/chrome/common/json_pref_store.h b/chrome/common/json_pref_store.h index d8da37d..b2a1f53 100644 --- a/chrome/common/json_pref_store.h +++ b/chrome/common/json_pref_store.h @@ -27,11 +27,6 @@ class Value; class JsonPrefStore : public PersistentPrefStore, public ImportantFileWriter::DataSerializer { public: - class Delegate { - public: - virtual void OnPrefsRead(PrefReadError error, bool no_dir) = 0; - }; - // |file_message_loop_proxy| is the MessageLoopProxy for a thread on which // file I/O can be done. JsonPrefStore(const FilePath& pref_filename, @@ -51,17 +46,11 @@ class JsonPrefStore : public PersistentPrefStore, virtual void RemoveValue(const std::string& key); virtual bool ReadOnly() const; virtual PrefReadError ReadPrefs(); - // todo(altimofeev): move it to the PersistentPrefStore inteface. - void ReadPrefs(Delegate* delegate); virtual bool WritePrefs(); virtual void ScheduleWritePrefs(); virtual void CommitPendingWrite(); virtual void ReportValueChanged(const std::string& key); - // This method is called after JSON file has been read. Method takes - // ownership of the |value| pointer. - void OnFileRead(Value* value_owned, PrefReadError error, bool no_dir); - private: // ImportantFileWriter::DataSerializer overrides: virtual bool SerializeData(std::string* output); @@ -77,8 +66,6 @@ class JsonPrefStore : public PersistentPrefStore, ObserverList<PrefStore::Observer, true> observers_; - Delegate* delegate_; - DISALLOW_COPY_AND_ASSIGN(JsonPrefStore); }; diff --git a/chrome/test/live_sync/live_sync_test.cc b/chrome/test/live_sync/live_sync_test.cc index 17fd1ab..d12624f 100644 --- a/chrome/test/live_sync/live_sync_test.cc +++ b/chrome/test/live_sync/live_sync_test.cc @@ -190,9 +190,7 @@ void LiveSyncTest::SetUpCommandLine(CommandLine* cl) { Profile* LiveSyncTest::MakeProfile(const FilePath::StringType name) { FilePath path; PathService::Get(chrome::DIR_USER_DATA, &path); - - ProfileManager* profile_manager = g_browser_process->profile_manager(); - return profile_manager->GetProfile(path.Append(name)); + return ProfileManager::CreateProfile(path.Append(name)); } Profile* LiveSyncTest::GetProfile(int index) { diff --git a/chrome/test/testing_pref_service.cc b/chrome/test/testing_pref_service.cc index dd09465..7d2a5c1 100644 --- a/chrome/test/testing_pref_service.cc +++ b/chrome/test/testing_pref_service.cc @@ -22,8 +22,7 @@ TestingPrefServiceBase::TestingPrefServiceBase( user_prefs, recommended_platform_prefs, NULL, - new DefaultPrefStore(), - NULL), + new DefaultPrefStore()), managed_platform_prefs_(managed_platform_prefs), user_prefs_(user_prefs), recommended_platform_prefs_(recommended_platform_prefs) { diff --git a/chrome_frame/test/net/fake_external_tab.cc b/chrome_frame/test/net/fake_external_tab.cc index b2473d99..a4bd592 100644 --- a/chrome_frame/test/net/fake_external_tab.cc +++ b/chrome_frame/test/net/fake_external_tab.cc @@ -15,7 +15,6 @@ #include "base/file_util.h" #include "base/file_version_info.h" #include "base/i18n/icu_util.h" -#include "base/memory/scoped_ptr.h" #include "base/path_service.h" #include "base/string_util.h" #include "base/stringprintf.h" @@ -103,22 +102,6 @@ bool SetFocusToAccessibleWindow(HWND hwnd) { return ret; } -// Same as BrowserProcessImpl, but uses custom profile manager. -class FakeBrowserProcessImpl : public BrowserProcessImpl { - public: - explicit FakeBrowserProcessImpl(const CommandLine& command_line) - : BrowserProcessImpl(command_line) {} - - virtual ProfileManager* profile_manager() { - if (!profile_manager_.get()) - profile_manager_.reset(new ProfileManagerWithoutInit); - return profile_manager_.get(); - } - - private: - scoped_ptr<ProfileManager> profile_manager_; -}; - } // namespace @@ -230,7 +213,7 @@ void FakeExternalTab::Initialize() { cmd->AppendSwitch(switches::kDisableWebResources); cmd->AppendSwitch(switches::kSingleProcess); - browser_process_.reset(new FakeBrowserProcessImpl(*cmd)); + browser_process_.reset(new BrowserProcessImpl(*cmd)); // BrowserProcessImpl's constructor should set g_browser_process. DCHECK(g_browser_process); g_browser_process->SetApplicationLocale("en-US"); @@ -239,8 +222,8 @@ void FakeExternalTab::Initialize() { browser::RegisterLocalState(browser_process_->local_state()); FilePath profile_path(ProfileManager::GetDefaultProfileDir(user_data())); - Profile* profile = - g_browser_process->profile_manager()->GetProfile(profile_path); + Profile* profile = g_browser_process->profile_manager()->GetProfile( + profile_path, false); // Create the child threads. g_browser_process->db_thread(); g_browser_process->file_thread(); |