| 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 b7327eacb0087770dbae3129bc2520d0223a6f57..b42e2de7b59e68dfb6561602bd3a716c368c4258 100644
|
| --- a/chrome/browser/ui/app_list/app_list_view_delegate.cc
|
| +++ b/chrome/browser/ui/app_list/app_list_view_delegate.cc
|
| @@ -35,6 +35,7 @@
|
| #include "chrome/common/url_constants.h"
|
| #include "components/signin/core/browser/signin_manager.h"
|
| #include "content/public/browser/browser_thread.h"
|
| +#include "content/public/browser/notification_service.h"
|
| #include "content/public/browser/page_navigator.h"
|
| #include "content/public/browser/user_metrics.h"
|
| #include "content/public/browser/web_contents.h"
|
| @@ -181,9 +182,16 @@ AppListViewDelegate::AppListViewDelegate(Profile* profile,
|
| IDR_APP_LIST_GOOGLE_LOGO_VOICE_SEARCH));
|
| #endif
|
| SetProfile(profile);
|
| +
|
| + registrar_.Add(this,
|
| + chrome::NOTIFICATION_APP_TERMINATING,
|
| + content::NotificationService::AllSources());
|
| }
|
|
|
| AppListViewDelegate::~AppListViewDelegate() {
|
| + // Note that the destructor is not always called. E.g. on Mac, this is owned
|
| + // by a leaky singleton. Essential shutdown work must be done by observing
|
| + // chrome::NOTIFICATION_APP_TERMINATING.
|
| SetProfile(NULL);
|
| g_browser_process->profile_manager()->GetProfileInfoCache().RemoveObserver(
|
| this);
|
| @@ -194,6 +202,9 @@ AppListViewDelegate::~AppListViewDelegate() {
|
| }
|
|
|
| void AppListViewDelegate::SetProfile(Profile* new_profile) {
|
| + if (profile_ == new_profile)
|
| + return;
|
| +
|
| if (profile_) {
|
| // Note: |search_controller_| has a reference to |speech_ui_| so must be
|
| // destroyed first.
|
| @@ -248,6 +259,11 @@ void AppListViewDelegate::SetUpSearchUI() {
|
| }
|
|
|
| void AppListViewDelegate::SetUpProfileSwitcher() {
|
| + // If a profile change is observed when there is no app list, there is nothing
|
| + // to update until SetProfile() calls this function again.
|
| + if (!profile_)
|
| + return;
|
| +
|
| // Don't populate the app list users if we are on the ash desktop.
|
| chrome::HostDesktopType desktop = chrome::GetHostDesktopTypeForNativeWindow(
|
| controller_->GetAppListWindow());
|
| @@ -439,6 +455,9 @@ void AppListViewDelegate::Dismiss() {
|
| void AppListViewDelegate::ViewClosing() {
|
| controller_->ViewClosing();
|
|
|
| + if (!profile_)
|
| + return;
|
| +
|
| app_list::StartPageService* service =
|
| app_list::StartPageService::Get(profile_);
|
| if (service) {
|
| @@ -623,3 +642,20 @@ void AppListViewDelegate::RemoveObserver(
|
| app_list::AppListViewDelegateObserver* observer) {
|
| observers_.RemoveObserver(observer);
|
| }
|
| +
|
| +void AppListViewDelegate::Observe(int type,
|
| + const content::NotificationSource& source,
|
| + const content::NotificationDetails& details) {
|
| + switch (type) {
|
| + case chrome::NOTIFICATION_APP_TERMINATING:
|
| + SetProfile(NULL); // Ensures launcher page web contents are torn down.
|
| +
|
| + // SigninManagerFactory is not a leaky singleton (unlike this class), and
|
| + // its destructor will check that it has no remaining observers.
|
| + scoped_observer_.RemoveAll();
|
| + SigninManagerFactory::GetInstance()->RemoveObserver(this);
|
| + break;
|
| + default:
|
| + NOTREACHED();
|
| + }
|
| +}
|
|
|