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

Side by Side 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, 3 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/ui/app_list/app_list_view_delegate.h" 5 #include "chrome/browser/ui/app_list/app_list_view_delegate.h"
6 6
7 #include <vector> 7 #include <vector>
8 8
9 #include "apps/custom_launcher_page_contents.h" 9 #include "apps/custom_launcher_page_contents.h"
10 #include "base/callback.h" 10 #include "base/callback.h"
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
150 } 150 }
151 urls->push_back(extension->GetResourceURL(launcher_page_page)); 151 urls->push_back(extension->GetResourceURL(launcher_page_page));
152 } 152 }
153 } 153 }
154 154
155 } // namespace 155 } // namespace
156 156
157 AppListViewDelegate::AppListViewDelegate(Profile* profile, 157 AppListViewDelegate::AppListViewDelegate(Profile* profile,
158 AppListControllerDelegate* controller) 158 AppListControllerDelegate* controller)
159 : controller_(controller), 159 : controller_(controller),
160 profile_(profile), 160 profile_(NULL),
161 model_(NULL), 161 model_(NULL),
162 scoped_observer_(this) { 162 scoped_observer_(this) {
163 CHECK(controller_); 163 CHECK(controller_);
164 // The SigninManagerFactor and the SigninManagers are observed to keep the 164 // The SigninManagerFactor and the SigninManagers are observed to keep the
165 // profile switcher menu up to date, with the correct list of profiles and the 165 // profile switcher menu up to date, with the correct list of profiles and the
166 // correct email address (or none for signed out users) for each. 166 // correct email address (or none for signed out users) for each.
167 SigninManagerFactory::GetInstance()->AddObserver(this); 167 SigninManagerFactory::GetInstance()->AddObserver(this);
168 168
169 // Start observing all already-created SigninManagers. 169 // Start observing all already-created SigninManagers.
170 ProfileManager* profile_manager = g_browser_process->profile_manager(); 170 ProfileManager* profile_manager = g_browser_process->profile_manager();
171 std::vector<Profile*> profiles = profile_manager->GetLoadedProfiles(); 171 std::vector<Profile*> profiles = profile_manager->GetLoadedProfiles();
172 for (std::vector<Profile*>::iterator i = profiles.begin(); 172 for (std::vector<Profile*>::iterator i = profiles.begin();
173 i != profiles.end(); 173 i != profiles.end();
174 ++i) { 174 ++i) {
175 SigninManagerBase* manager = 175 SigninManagerBase* manager =
176 SigninManagerFactory::GetForProfileIfExists(*i); 176 SigninManagerFactory::GetForProfileIfExists(*i);
177 if (manager) { 177 if (manager) {
178 DCHECK(!scoped_observer_.IsObserving(manager)); 178 DCHECK(!scoped_observer_.IsObserving(manager));
179 scoped_observer_.Add(manager); 179 scoped_observer_.Add(manager);
180 } 180 }
181 } 181 }
182 182
183 profile_manager->GetProfileInfoCache().AddObserver(this); 183 profile_manager->GetProfileInfoCache().AddObserver(this);
184 SetProfile(profile);
185 }
184 186
185 app_list::StartPageService* service = 187 void AppListViewDelegate::SetProfile(Profile* new_profile) {
188 if (profile_) {
189 // Note: |search_controller_| has a reference to |speech_ui_| so must be
190 // destroyed first.
191 search_controller_.reset();
192 speech_ui_.reset();
193 custom_page_contents_.clear();
194 app_list::StartPageService* start_page_service =
195 app_list::StartPageService::Get(profile_);
196 if (start_page_service)
197 start_page_service->RemoveObserver(this);
198 #if defined(USE_ASH)
199 app_sync_ui_state_watcher_.reset();
200 #endif
201 model_ = NULL;
202 }
203
204 profile_ = new_profile;
205 if (!profile_)
206 return;
207
208 model_ =
209 app_list::AppListSyncableServiceFactory::GetForProfile(profile_)->model();
210
211 #if defined(USE_ASH)
212 app_sync_ui_state_watcher_.reset(new AppSyncUIStateWatcher(profile_, model_));
213 #endif
214
215 SetUpSearchUI();
216 SetUpProfileSwitcher();
217 SetUpCustomLauncherPages();
218
219 // Clear search query.
220 model_->search_box()->SetText(base::string16());
221 }
222
223 void AppListViewDelegate::SetUpSearchUI() {
224 app_list::StartPageService* start_page_service =
186 app_list::StartPageService::Get(profile_); 225 app_list::StartPageService::Get(profile_);
226 if (start_page_service)
227 start_page_service->AddObserver(this);
228
187 speech_ui_.reset(new app_list::SpeechUIModel( 229 speech_ui_.reset(new app_list::SpeechUIModel(
188 service ? service->state() : app_list::SPEECH_RECOGNITION_OFF)); 230 start_page_service ? start_page_service->state()
231 : app_list::SPEECH_RECOGNITION_OFF));
189 232
190 #if defined(GOOGLE_CHROME_BUILD) 233 #if defined(GOOGLE_CHROME_BUILD)
191 speech_ui_->set_logo( 234 speech_ui_->set_logo(
192 *ui::ResourceBundle::GetSharedInstance(). 235 *ui::ResourceBundle::GetSharedInstance().
193 GetImageSkiaNamed(IDR_APP_LIST_GOOGLE_LOGO_VOICE_SEARCH)); 236 GetImageSkiaNamed(IDR_APP_LIST_GOOGLE_LOGO_VOICE_SEARCH));
194 #endif 237 #endif
195 238
196 OnProfileChanged(); // sets model_ 239 search_controller_.reset(new app_list::SearchController(profile_,
197 if (service) 240 model_->search_box(),
198 service->AddObserver(this); 241 model_->results(),
242 speech_ui_.get(),
243 controller_));
244 }
199 245
200 // Set up the custom launcher pages. 246 void AppListViewDelegate::SetUpCustomLauncherPages() {
201 std::vector<GURL> custom_launcher_page_urls; 247 std::vector<GURL> custom_launcher_page_urls;
202 GetCustomLauncherPageUrls(profile, &custom_launcher_page_urls); 248 GetCustomLauncherPageUrls(profile_, &custom_launcher_page_urls);
203 for (std::vector<GURL>::const_iterator it = custom_launcher_page_urls.begin(); 249 for (std::vector<GURL>::const_iterator it = custom_launcher_page_urls.begin();
204 it != custom_launcher_page_urls.end(); 250 it != custom_launcher_page_urls.end();
205 ++it) { 251 ++it) {
206 std::string extension_id = it->host(); 252 std::string extension_id = it->host();
207 apps::CustomLauncherPageContents* page_contents = 253 apps::CustomLauncherPageContents* page_contents =
208 new apps::CustomLauncherPageContents( 254 new apps::CustomLauncherPageContents(
209 scoped_ptr<extensions::AppDelegate>(new ChromeAppDelegate), 255 scoped_ptr<extensions::AppDelegate>(new ChromeAppDelegate),
210 extension_id); 256 extension_id);
211 page_contents->Initialize(profile, *it); 257 page_contents->Initialize(profile_, *it);
212 custom_page_contents_.push_back(page_contents); 258 custom_page_contents_.push_back(page_contents);
213 } 259 }
214 } 260 }
215 261
216 AppListViewDelegate::~AppListViewDelegate() { 262 AppListViewDelegate::~AppListViewDelegate() {
217 app_list::StartPageService* service = 263 SetProfile(NULL);
218 app_list::StartPageService::Get(profile_); 264 g_browser_process->profile_manager()->GetProfileInfoCache().RemoveObserver(
219 if (service) 265 this);
220 service->RemoveObserver(this);
221 g_browser_process->
222 profile_manager()->GetProfileInfoCache().RemoveObserver(this);
223 266
224 SigninManagerFactory* factory = SigninManagerFactory::GetInstance(); 267 SigninManagerFactory* factory = SigninManagerFactory::GetInstance();
225 if (factory) 268 if (factory)
226 factory->RemoveObserver(this); 269 factory->RemoveObserver(this);
227
228 // Ensure search controller is released prior to speech_ui_.
229 search_controller_.reset();
230 } 270 }
231 271
232 void AppListViewDelegate::OnHotwordStateChanged(bool started) { 272 void AppListViewDelegate::OnHotwordStateChanged(bool started) {
233 if (started) { 273 if (started) {
234 if (speech_ui_->state() == app_list::SPEECH_RECOGNITION_READY) { 274 if (speech_ui_->state() == app_list::SPEECH_RECOGNITION_READY) {
235 OnSpeechRecognitionStateChanged( 275 OnSpeechRecognitionStateChanged(
236 app_list::SPEECH_RECOGNITION_HOTWORD_LISTENING); 276 app_list::SPEECH_RECOGNITION_HOTWORD_LISTENING);
237 } 277 }
238 } else { 278 } else {
239 if (speech_ui_->state() == app_list::SPEECH_RECOGNITION_HOTWORD_LISTENING) 279 if (speech_ui_->state() == app_list::SPEECH_RECOGNITION_HOTWORD_LISTENING)
(...skipping 11 matching lines...) Expand all
251 scoped_observer_.Add(manager); 291 scoped_observer_.Add(manager);
252 } 292 }
253 293
254 void AppListViewDelegate::SigninManagerShutdown(SigninManagerBase* manager) { 294 void AppListViewDelegate::SigninManagerShutdown(SigninManagerBase* manager) {
255 if (scoped_observer_.IsObserving(manager)) 295 if (scoped_observer_.IsObserving(manager))
256 scoped_observer_.Remove(manager); 296 scoped_observer_.Remove(manager);
257 } 297 }
258 298
259 void AppListViewDelegate::GoogleSigninFailed( 299 void AppListViewDelegate::GoogleSigninFailed(
260 const GoogleServiceAuthError& error) { 300 const GoogleServiceAuthError& error) {
261 OnProfileChanged(); 301 SetUpProfileSwitcher();
262 } 302 }
263 303
264 void AppListViewDelegate::GoogleSigninSucceeded(const std::string& username, 304 void AppListViewDelegate::GoogleSigninSucceeded(const std::string& username,
265 const std::string& password) { 305 const std::string& password) {
266 OnProfileChanged(); 306 SetUpProfileSwitcher();
267 } 307 }
268 308
269 void AppListViewDelegate::GoogleSignedOut(const std::string& username) { 309 void AppListViewDelegate::GoogleSignedOut(const std::string& username) {
270 OnProfileChanged(); 310 SetUpProfileSwitcher();
271 } 311 }
272 312
273 void AppListViewDelegate::OnProfileChanged() { 313 void AppListViewDelegate::SetUpProfileSwitcher() {
274 model_ = app_list::AppListSyncableServiceFactory::GetForProfile(
275 profile_)->model();
276
277 search_controller_.reset(new app_list::SearchController(
278 profile_, model_->search_box(), model_->results(),
279 speech_ui_.get(), controller_));
280
281 #if defined(USE_ASH)
282 app_sync_ui_state_watcher_.reset(new AppSyncUIStateWatcher(profile_, model_));
283 #endif
284
285 // Don't populate the app list users if we are on the ash desktop. 314 // Don't populate the app list users if we are on the ash desktop.
286 chrome::HostDesktopType desktop = chrome::GetHostDesktopTypeForNativeWindow( 315 chrome::HostDesktopType desktop = chrome::GetHostDesktopTypeForNativeWindow(
287 controller_->GetAppListWindow()); 316 controller_->GetAppListWindow());
288 if (desktop == chrome::HOST_DESKTOP_TYPE_ASH) 317 if (desktop == chrome::HOST_DESKTOP_TYPE_ASH)
289 return; 318 return;
290 319
291 // Populate the app list users. 320 // Populate the app list users.
292 PopulateUsers(g_browser_process->profile_manager()->GetProfileInfoCache(), 321 PopulateUsers(g_browser_process->profile_manager()->GetProfileInfoCache(),
293 profile_->GetPath(), &users_); 322 profile_->GetPath(),
323 &users_);
294 324
295 FOR_EACH_OBSERVER(app_list::AppListViewDelegateObserver, 325 FOR_EACH_OBSERVER(
296 observers_, 326 app_list::AppListViewDelegateObserver, observers_, OnProfilesChanged());
297 OnProfilesChanged());
298 } 327 }
299 328
300 bool AppListViewDelegate::ForceNativeDesktop() const { 329 bool AppListViewDelegate::ForceNativeDesktop() const {
301 return controller_->ForceNativeDesktop(); 330 return controller_->ForceNativeDesktop();
302 } 331 }
303 332
304 void AppListViewDelegate::SetProfileByPath(const base::FilePath& profile_path) { 333 void AppListViewDelegate::SetProfileByPath(const base::FilePath& profile_path) {
305 DCHECK(model_); 334 DCHECK(model_);
306
307 // The profile must be loaded before this is called. 335 // The profile must be loaded before this is called.
308 profile_ = 336 SetProfile(
309 g_browser_process->profile_manager()->GetProfileByPath(profile_path); 337 g_browser_process->profile_manager()->GetProfileByPath(profile_path));
310 DCHECK(profile_);
311
312 OnProfileChanged();
313
314 // Clear search query.
315 model_->search_box()->SetText(base::string16());
316 } 338 }
317 339
318 app_list::AppListModel* AppListViewDelegate::GetModel() { 340 app_list::AppListModel* AppListViewDelegate::GetModel() {
319 return model_; 341 return model_;
320 } 342 }
321 343
322 app_list::SpeechUIModel* AppListViewDelegate::GetSpeechUI() { 344 app_list::SpeechUIModel* AppListViewDelegate::GetSpeechUI() {
323 return speech_ui_.get(); 345 return speech_ui_.get();
324 } 346 }
325 347
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
493 service && service->HotwordEnabled()) { 515 service && service->HotwordEnabled()) {
494 HotwordService* hotword_service = 516 HotwordService* hotword_service =
495 HotwordServiceFactory::GetForProfile(profile_); 517 HotwordServiceFactory::GetForProfile(profile_);
496 if (hotword_service) { 518 if (hotword_service) {
497 hotword_service->RequestHotwordSession(this); 519 hotword_service->RequestHotwordSession(this);
498 } 520 }
499 } 521 }
500 } 522 }
501 523
502 void AppListViewDelegate::OnProfileAdded(const base::FilePath& profile_path) { 524 void AppListViewDelegate::OnProfileAdded(const base::FilePath& profile_path) {
503 OnProfileChanged(); 525 SetUpProfileSwitcher();
504 } 526 }
505 527
506 void AppListViewDelegate::OnProfileWasRemoved( 528 void AppListViewDelegate::OnProfileWasRemoved(
507 const base::FilePath& profile_path, const base::string16& profile_name) { 529 const base::FilePath& profile_path,
508 OnProfileChanged(); 530 const base::string16& profile_name) {
531 SetUpProfileSwitcher();
509 } 532 }
510 533
511 void AppListViewDelegate::OnProfileNameChanged( 534 void AppListViewDelegate::OnProfileNameChanged(
512 const base::FilePath& profile_path, 535 const base::FilePath& profile_path,
513 const base::string16& old_profile_name) { 536 const base::string16& old_profile_name) {
514 OnProfileChanged(); 537 SetUpProfileSwitcher();
515 } 538 }
516 539
517 #if defined(TOOLKIT_VIEWS) 540 #if defined(TOOLKIT_VIEWS)
518 views::View* AppListViewDelegate::CreateStartPageWebView( 541 views::View* AppListViewDelegate::CreateStartPageWebView(
519 const gfx::Size& size) { 542 const gfx::Size& size) {
520 app_list::StartPageService* service = 543 app_list::StartPageService* service =
521 app_list::StartPageService::Get(profile_); 544 app_list::StartPageService::Get(profile_);
522 if (!service) 545 if (!service)
523 return NULL; 546 return NULL;
524 547
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
597 620
598 void AppListViewDelegate::AddObserver( 621 void AppListViewDelegate::AddObserver(
599 app_list::AppListViewDelegateObserver* observer) { 622 app_list::AppListViewDelegateObserver* observer) {
600 observers_.AddObserver(observer); 623 observers_.AddObserver(observer);
601 } 624 }
602 625
603 void AppListViewDelegate::RemoveObserver( 626 void AppListViewDelegate::RemoveObserver(
604 app_list::AppListViewDelegateObserver* observer) { 627 app_list::AppListViewDelegateObserver* observer) {
605 observers_.RemoveObserver(observer); 628 observers_.RemoveObserver(observer);
606 } 629 }
OLDNEW
« 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