Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(89)

Unified Diff: chrome/browser/ui/app_list/app_list_view_delegate.cc

Issue 492163002: Fix Profile* lifetime issues in Chrome's AppListViewDelegate (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: reorder functions for a neater diff Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/ui/app_list/app_list_view_delegate.cc
diff --git a/chrome/browser/ui/app_list/app_list_view_delegate.cc b/chrome/browser/ui/app_list/app_list_view_delegate.cc
index 382de360605b707b7950c2ffcdd5f48f09e7a707..80e9fbebe3ab91351f1f34b7a52e64908910fd7f 100644
--- a/chrome/browser/ui/app_list/app_list_view_delegate.cc
+++ b/chrome/browser/ui/app_list/app_list_view_delegate.cc
@@ -157,7 +157,7 @@ void GetCustomLauncherPageUrls(content::BrowserContext* browser_context,
AppListViewDelegate::AppListViewDelegate(Profile* profile,
AppListControllerDelegate* controller)
: controller_(controller),
- profile_(profile),
+ profile_(NULL),
model_(NULL),
scoped_observer_(this) {
CHECK(controller_);
@@ -181,11 +181,54 @@ AppListViewDelegate::AppListViewDelegate(Profile* profile,
}
profile_manager->GetProfileInfoCache().AddObserver(this);
+ SetProfile(profile);
+}
+
+void AppListViewDelegate::SetProfile(Profile* new_profile) {
+ if (profile_) {
+ // Note: |search_controller_| has a reference to |speech_ui_| so must be
+ // destroyed first.
+ search_controller_.reset();
+ speech_ui_.reset();
+ custom_page_contents_.clear();
+ app_list::StartPageService* start_page_service =
+ app_list::StartPageService::Get(profile_);
+ if (start_page_service)
+ start_page_service->RemoveObserver(this);
+#if defined(USE_ASH)
+ app_sync_ui_state_watcher_.reset();
+#endif
+ model_ = NULL;
+ }
- app_list::StartPageService* service =
+ profile_ = new_profile;
+ if (!profile_)
+ return;
+
+ model_ =
+ app_list::AppListSyncableServiceFactory::GetForProfile(profile_)->model();
+
+#if defined(USE_ASH)
+ app_sync_ui_state_watcher_.reset(new AppSyncUIStateWatcher(profile_, model_));
+#endif
+
+ SetUpSearchUI();
+ SetUpProfileSwitcher();
+ SetUpCustomLauncherPages();
+
+ // Clear search query.
+ model_->search_box()->SetText(base::string16());
+}
+
+void AppListViewDelegate::SetUpSearchUI() {
+ app_list::StartPageService* start_page_service =
app_list::StartPageService::Get(profile_);
+ if (start_page_service)
+ start_page_service->AddObserver(this);
+
speech_ui_.reset(new app_list::SpeechUIModel(
- service ? service->state() : app_list::SPEECH_RECOGNITION_OFF));
+ start_page_service ? start_page_service->state()
+ : app_list::SPEECH_RECOGNITION_OFF));
#if defined(GOOGLE_CHROME_BUILD)
speech_ui_->set_logo(
@@ -193,13 +236,16 @@ AppListViewDelegate::AppListViewDelegate(Profile* profile,
GetImageSkiaNamed(IDR_APP_LIST_GOOGLE_LOGO_VOICE_SEARCH));
#endif
- OnProfileChanged(); // sets model_
- if (service)
- service->AddObserver(this);
+ search_controller_.reset(new app_list::SearchController(profile_,
+ model_->search_box(),
+ model_->results(),
+ speech_ui_.get(),
+ controller_));
+}
- // Set up the custom launcher pages.
+void AppListViewDelegate::SetUpCustomLauncherPages() {
std::vector<GURL> custom_launcher_page_urls;
- GetCustomLauncherPageUrls(profile, &custom_launcher_page_urls);
+ GetCustomLauncherPageUrls(profile_, &custom_launcher_page_urls);
for (std::vector<GURL>::const_iterator it = custom_launcher_page_urls.begin();
it != custom_launcher_page_urls.end();
++it) {
@@ -208,25 +254,19 @@ AppListViewDelegate::AppListViewDelegate(Profile* profile,
new apps::CustomLauncherPageContents(
scoped_ptr<extensions::AppDelegate>(new ChromeAppDelegate),
extension_id);
- page_contents->Initialize(profile, *it);
+ page_contents->Initialize(profile_, *it);
custom_page_contents_.push_back(page_contents);
}
}
AppListViewDelegate::~AppListViewDelegate() {
- app_list::StartPageService* service =
- app_list::StartPageService::Get(profile_);
- if (service)
- service->RemoveObserver(this);
- g_browser_process->
- profile_manager()->GetProfileInfoCache().RemoveObserver(this);
+ SetProfile(NULL);
+ g_browser_process->profile_manager()->GetProfileInfoCache().RemoveObserver(
+ this);
SigninManagerFactory* factory = SigninManagerFactory::GetInstance();
if (factory)
factory->RemoveObserver(this);
-
- // Ensure search controller is released prior to speech_ui_.
- search_controller_.reset();
}
void AppListViewDelegate::OnHotwordStateChanged(bool started) {
@@ -258,30 +298,19 @@ void AppListViewDelegate::SigninManagerShutdown(SigninManagerBase* manager) {
void AppListViewDelegate::GoogleSigninFailed(
const GoogleServiceAuthError& error) {
- OnProfileChanged();
+ SetUpProfileSwitcher();
}
void AppListViewDelegate::GoogleSigninSucceeded(const std::string& username,
const std::string& password) {
- OnProfileChanged();
+ SetUpProfileSwitcher();
}
void AppListViewDelegate::GoogleSignedOut(const std::string& username) {
- OnProfileChanged();
+ SetUpProfileSwitcher();
}
-void AppListViewDelegate::OnProfileChanged() {
- model_ = app_list::AppListSyncableServiceFactory::GetForProfile(
- profile_)->model();
-
- search_controller_.reset(new app_list::SearchController(
- profile_, model_->search_box(), model_->results(),
- speech_ui_.get(), controller_));
-
-#if defined(USE_ASH)
- app_sync_ui_state_watcher_.reset(new AppSyncUIStateWatcher(profile_, model_));
-#endif
-
+void AppListViewDelegate::SetUpProfileSwitcher() {
// Don't populate the app list users if we are on the ash desktop.
chrome::HostDesktopType desktop = chrome::GetHostDesktopTypeForNativeWindow(
controller_->GetAppListWindow());
@@ -290,11 +319,11 @@ void AppListViewDelegate::OnProfileChanged() {
// Populate the app list users.
PopulateUsers(g_browser_process->profile_manager()->GetProfileInfoCache(),
- profile_->GetPath(), &users_);
+ profile_->GetPath(),
+ &users_);
- FOR_EACH_OBSERVER(app_list::AppListViewDelegateObserver,
- observers_,
- OnProfilesChanged());
+ FOR_EACH_OBSERVER(
+ app_list::AppListViewDelegateObserver, observers_, OnProfilesChanged());
}
bool AppListViewDelegate::ForceNativeDesktop() const {
@@ -303,16 +332,9 @@ bool AppListViewDelegate::ForceNativeDesktop() const {
void AppListViewDelegate::SetProfileByPath(const base::FilePath& profile_path) {
DCHECK(model_);
-
// The profile must be loaded before this is called.
- profile_ =
- g_browser_process->profile_manager()->GetProfileByPath(profile_path);
- DCHECK(profile_);
-
- OnProfileChanged();
-
- // Clear search query.
- model_->search_box()->SetText(base::string16());
+ SetProfile(
+ g_browser_process->profile_manager()->GetProfileByPath(profile_path));
}
app_list::AppListModel* AppListViewDelegate::GetModel() {
@@ -500,18 +522,19 @@ void AppListViewDelegate::OnSpeechRecognitionStateChanged(
}
void AppListViewDelegate::OnProfileAdded(const base::FilePath& profile_path) {
- OnProfileChanged();
+ SetUpProfileSwitcher();
}
void AppListViewDelegate::OnProfileWasRemoved(
- const base::FilePath& profile_path, const base::string16& profile_name) {
- OnProfileChanged();
+ const base::FilePath& profile_path,
+ const base::string16& profile_name) {
+ SetUpProfileSwitcher();
}
void AppListViewDelegate::OnProfileNameChanged(
const base::FilePath& profile_path,
const base::string16& old_profile_name) {
- OnProfileChanged();
+ SetUpProfileSwitcher();
}
#if defined(TOOLKIT_VIEWS)
« no previous file with comments | « chrome/browser/ui/app_list/app_list_view_delegate.h ('k') | chrome/browser/ui/ash/app_list/app_list_service_ash.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698