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

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: update unit test, cl format 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 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 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
147 << extensions::manifest_keys::kLauncherPage 147 << extensions::manifest_keys::kLauncherPage
148 << " has no 'page' attribute; will be ignored."; 148 << " has no 'page' attribute; will be ignored.";
149 continue; 149 continue;
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(
158 AppListControllerDelegate* controller) 158 AppListControllerDelegate* controller_delegate)
159 : controller_(controller), 159 : controller_(controller_delegate),
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 }
184 185
185 app_list::StartPageService* service = 186 AppListViewDelegate::~AppListViewDelegate() {
187 SetProfile(NULL);
188 g_browser_process->profile_manager()->GetProfileInfoCache().RemoveObserver(
189 this);
190
191 SigninManagerFactory* factory = SigninManagerFactory::GetInstance();
192 if (factory)
193 factory->RemoveObserver(this);
194 }
195
196 void AppListViewDelegate::SetProfile(Profile* new_profile) {
197 if (profile_) {
198 // Note: |search_controller_| has a reference to |speech_ui_| so must be
199 // destroyed first.
Matt Giuca 2014/08/25 04:48:46 Should you duplicate this comment where |search_co
tapted 2014/08/25 06:17:00 Done.
200 search_controller_.reset();
201 speech_ui_.reset();
202 custom_page_contents_.clear();
203 app_list::StartPageService* start_page_service =
204 app_list::StartPageService::Get(profile_);
205 if (start_page_service)
206 start_page_service->RemoveObserver(this);
207 #if defined(USE_ASH)
208 app_sync_ui_state_watcher_.reset();
209 #endif
210 model_ = NULL;
211 }
212
213 profile_ = new_profile;
214 if (!profile_)
215 return;
216
217 model_ =
218 app_list::AppListSyncableServiceFactory::GetForProfile(profile_)->model();
219
220 #if defined(USE_ASH)
221 app_sync_ui_state_watcher_.reset(new AppSyncUIStateWatcher(profile_, model_));
222 #endif
223
224 SetUpSearchUI();
225 SetUpProfileSwitcher();
226 SetUpCustomLauncherPages();
227
228 // Clear search query.
229 model_->search_box()->SetText(base::string16());
230 }
231
232 void AppListViewDelegate::SetUpSearchUI() {
233 app_list::StartPageService* start_page_service =
186 app_list::StartPageService::Get(profile_); 234 app_list::StartPageService::Get(profile_);
235 if (start_page_service)
236 start_page_service->AddObserver(this);
237
187 speech_ui_.reset(new app_list::SpeechUIModel( 238 speech_ui_.reset(new app_list::SpeechUIModel(
188 service ? service->state() : app_list::SPEECH_RECOGNITION_OFF)); 239 start_page_service ? start_page_service->state()
240 : app_list::SPEECH_RECOGNITION_OFF));
189 241
190 #if defined(GOOGLE_CHROME_BUILD) 242 #if defined(GOOGLE_CHROME_BUILD)
191 speech_ui_->set_logo( 243 speech_ui_->set_logo(
192 *ui::ResourceBundle::GetSharedInstance(). 244 *ui::ResourceBundle::GetSharedInstance().
193 GetImageSkiaNamed(IDR_APP_LIST_GOOGLE_LOGO_VOICE_SEARCH)); 245 GetImageSkiaNamed(IDR_APP_LIST_GOOGLE_LOGO_VOICE_SEARCH));
194 #endif 246 #endif
195 247
196 OnProfileChanged(); // sets model_ 248 search_controller_.reset(new app_list::SearchController(profile_,
197 if (service) 249 model_->search_box(),
198 service->AddObserver(this); 250 model_->results(),
251 speech_ui_.get(),
252 controller_));
253 }
199 254
200 // Set up the custom launcher pages. 255 void AppListViewDelegate::SetUpProfileSwitcher() {
256 // Don't populate the app list users if we are on the ash desktop.
257 chrome::HostDesktopType desktop = chrome::GetHostDesktopTypeForNativeWindow(
258 controller_->GetAppListWindow());
259 if (desktop == chrome::HOST_DESKTOP_TYPE_ASH)
260 return;
261
262 // Populate the app list users.
263 PopulateUsers(g_browser_process->profile_manager()->GetProfileInfoCache(),
264 profile_->GetPath(),
265 &users_);
266
267 FOR_EACH_OBSERVER(
268 app_list::AppListViewDelegateObserver, observers_, OnProfilesChanged());
269 }
270
271 void AppListViewDelegate::SetUpCustomLauncherPages() {
201 std::vector<GURL> custom_launcher_page_urls; 272 std::vector<GURL> custom_launcher_page_urls;
202 GetCustomLauncherPageUrls(profile, &custom_launcher_page_urls); 273 GetCustomLauncherPageUrls(profile_, &custom_launcher_page_urls);
203 for (std::vector<GURL>::const_iterator it = custom_launcher_page_urls.begin(); 274 for (std::vector<GURL>::const_iterator it = custom_launcher_page_urls.begin();
204 it != custom_launcher_page_urls.end(); 275 it != custom_launcher_page_urls.end();
205 ++it) { 276 ++it) {
206 std::string extension_id = it->host(); 277 std::string extension_id = it->host();
207 apps::CustomLauncherPageContents* page_contents = 278 apps::CustomLauncherPageContents* page_contents =
208 new apps::CustomLauncherPageContents( 279 new apps::CustomLauncherPageContents(
209 scoped_ptr<extensions::AppDelegate>(new ChromeAppDelegate), 280 scoped_ptr<extensions::AppDelegate>(new ChromeAppDelegate),
210 extension_id); 281 extension_id);
211 page_contents->Initialize(profile, *it); 282 page_contents->Initialize(profile_, *it);
212 custom_page_contents_.push_back(page_contents); 283 custom_page_contents_.push_back(page_contents);
213 } 284 }
214 } 285 }
215 286
216 AppListViewDelegate::~AppListViewDelegate() {
217 app_list::StartPageService* service =
218 app_list::StartPageService::Get(profile_);
219 if (service)
220 service->RemoveObserver(this);
221 g_browser_process->
222 profile_manager()->GetProfileInfoCache().RemoveObserver(this);
223
224 SigninManagerFactory* factory = SigninManagerFactory::GetInstance();
225 if (factory)
226 factory->RemoveObserver(this);
227
228 // Ensure search controller is released prior to speech_ui_.
229 search_controller_.reset();
230 }
231
232 void AppListViewDelegate::OnHotwordStateChanged(bool started) { 287 void AppListViewDelegate::OnHotwordStateChanged(bool started) {
233 if (started) { 288 if (started) {
234 if (speech_ui_->state() == app_list::SPEECH_RECOGNITION_READY) { 289 if (speech_ui_->state() == app_list::SPEECH_RECOGNITION_READY) {
235 OnSpeechRecognitionStateChanged( 290 OnSpeechRecognitionStateChanged(
236 app_list::SPEECH_RECOGNITION_HOTWORD_LISTENING); 291 app_list::SPEECH_RECOGNITION_HOTWORD_LISTENING);
237 } 292 }
238 } else { 293 } else {
239 if (speech_ui_->state() == app_list::SPEECH_RECOGNITION_HOTWORD_LISTENING) 294 if (speech_ui_->state() == app_list::SPEECH_RECOGNITION_HOTWORD_LISTENING)
240 OnSpeechRecognitionStateChanged(app_list::SPEECH_RECOGNITION_READY); 295 OnSpeechRecognitionStateChanged(app_list::SPEECH_RECOGNITION_READY);
241 } 296 }
242 } 297 }
243 298
244 void AppListViewDelegate::OnHotwordRecognized() { 299 void AppListViewDelegate::OnHotwordRecognized() {
245 DCHECK_EQ(app_list::SPEECH_RECOGNITION_HOTWORD_LISTENING, 300 DCHECK_EQ(app_list::SPEECH_RECOGNITION_HOTWORD_LISTENING,
246 speech_ui_->state()); 301 speech_ui_->state());
247 ToggleSpeechRecognition(); 302 ToggleSpeechRecognition();
248 } 303 }
249 304
250 void AppListViewDelegate::SigninManagerCreated(SigninManagerBase* manager) { 305 void AppListViewDelegate::SigninManagerCreated(SigninManagerBase* manager) {
251 scoped_observer_.Add(manager); 306 scoped_observer_.Add(manager);
252 } 307 }
253 308
254 void AppListViewDelegate::SigninManagerShutdown(SigninManagerBase* manager) { 309 void AppListViewDelegate::SigninManagerShutdown(SigninManagerBase* manager) {
255 if (scoped_observer_.IsObserving(manager)) 310 if (scoped_observer_.IsObserving(manager))
256 scoped_observer_.Remove(manager); 311 scoped_observer_.Remove(manager);
257 } 312 }
258 313
259 void AppListViewDelegate::GoogleSigninFailed( 314 void AppListViewDelegate::GoogleSigninFailed(
260 const GoogleServiceAuthError& error) { 315 const GoogleServiceAuthError& error) {
261 OnProfileChanged(); 316 SetUpProfileSwitcher();
262 } 317 }
263 318
264 void AppListViewDelegate::GoogleSigninSucceeded(const std::string& username, 319 void AppListViewDelegate::GoogleSigninSucceeded(const std::string& username,
265 const std::string& password) { 320 const std::string& password) {
266 OnProfileChanged(); 321 SetUpProfileSwitcher();
267 } 322 }
268 323
269 void AppListViewDelegate::GoogleSignedOut(const std::string& username) { 324 void AppListViewDelegate::GoogleSignedOut(const std::string& username) {
270 OnProfileChanged(); 325 SetUpProfileSwitcher();
271 } 326 }
272 327
273 void AppListViewDelegate::OnProfileChanged() { 328 void AppListViewDelegate::OnProfileAdded(const base::FilePath& profile_path) {
274 model_ = app_list::AppListSyncableServiceFactory::GetForProfile( 329 SetUpProfileSwitcher();
275 profile_)->model(); 330 }
276 331
277 search_controller_.reset(new app_list::SearchController( 332 void AppListViewDelegate::OnProfileWasRemoved(
278 profile_, model_->search_box(), model_->results(), 333 const base::FilePath& profile_path,
279 speech_ui_.get(), controller_)); 334 const base::string16& profile_name) {
335 SetUpProfileSwitcher();
336 }
280 337
281 #if defined(USE_ASH) 338 void AppListViewDelegate::OnProfileNameChanged(
282 app_sync_ui_state_watcher_.reset(new AppSyncUIStateWatcher(profile_, model_)); 339 const base::FilePath& profile_path,
283 #endif 340 const base::string16& old_profile_name) {
284 341 SetUpProfileSwitcher();
285 // Don't populate the app list users if we are on the ash desktop.
286 chrome::HostDesktopType desktop = chrome::GetHostDesktopTypeForNativeWindow(
287 controller_->GetAppListWindow());
288 if (desktop == chrome::HOST_DESKTOP_TYPE_ASH)
289 return;
290
291 // Populate the app list users.
292 PopulateUsers(g_browser_process->profile_manager()->GetProfileInfoCache(),
293 profile_->GetPath(), &users_);
294
295 FOR_EACH_OBSERVER(app_list::AppListViewDelegateObserver,
296 observers_,
297 OnProfilesChanged());
298 } 342 }
299 343
300 bool AppListViewDelegate::ForceNativeDesktop() const { 344 bool AppListViewDelegate::ForceNativeDesktop() const {
301 return controller_->ForceNativeDesktop(); 345 return controller_->ForceNativeDesktop();
302 } 346 }
303 347
304 void AppListViewDelegate::SetProfileByPath(const base::FilePath& profile_path) { 348 void AppListViewDelegate::SetProfileByPath(const base::FilePath& profile_path) {
305 DCHECK(model_); 349 DCHECK(model_);
306
307 // The profile must be loaded before this is called. 350 // The profile must be loaded before this is called.
308 profile_ = 351 SetProfile(
309 g_browser_process->profile_manager()->GetProfileByPath(profile_path); 352 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 } 353 }
317 354
318 app_list::AppListModel* AppListViewDelegate::GetModel() { 355 app_list::AppListModel* AppListViewDelegate::GetModel() {
319 return model_; 356 return model_;
320 } 357 }
321 358
322 app_list::SpeechUIModel* AppListViewDelegate::GetSpeechUI() { 359 app_list::SpeechUIModel* AppListViewDelegate::GetSpeechUI() {
323 return speech_ui_.get(); 360 return speech_ui_.get();
324 } 361 }
325 362
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
492 HotwordService::IsExperimentalHotwordingEnabled() && 529 HotwordService::IsExperimentalHotwordingEnabled() &&
493 service && service->HotwordEnabled()) { 530 service && service->HotwordEnabled()) {
494 HotwordService* hotword_service = 531 HotwordService* hotword_service =
495 HotwordServiceFactory::GetForProfile(profile_); 532 HotwordServiceFactory::GetForProfile(profile_);
496 if (hotword_service) { 533 if (hotword_service) {
497 hotword_service->RequestHotwordSession(this); 534 hotword_service->RequestHotwordSession(this);
498 } 535 }
499 } 536 }
500 } 537 }
501 538
502 void AppListViewDelegate::OnProfileAdded(const base::FilePath& profile_path) {
503 OnProfileChanged();
504 }
505
506 void AppListViewDelegate::OnProfileWasRemoved(
507 const base::FilePath& profile_path, const base::string16& profile_name) {
508 OnProfileChanged();
509 }
510
511 void AppListViewDelegate::OnProfileNameChanged(
512 const base::FilePath& profile_path,
513 const base::string16& old_profile_name) {
514 OnProfileChanged();
515 }
516
517 #if defined(TOOLKIT_VIEWS) 539 #if defined(TOOLKIT_VIEWS)
518 views::View* AppListViewDelegate::CreateStartPageWebView( 540 views::View* AppListViewDelegate::CreateStartPageWebView(
519 const gfx::Size& size) { 541 const gfx::Size& size) {
520 app_list::StartPageService* service = 542 app_list::StartPageService* service =
521 app_list::StartPageService::Get(profile_); 543 app_list::StartPageService::Get(profile_);
522 if (!service) 544 if (!service)
523 return NULL; 545 return NULL;
524 546
525 content::WebContents* web_contents = service->GetStartPageContents(); 547 content::WebContents* web_contents = service->GetStartPageContents();
526 if (!web_contents) 548 if (!web_contents)
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
597 619
598 void AppListViewDelegate::AddObserver( 620 void AppListViewDelegate::AddObserver(
599 app_list::AppListViewDelegateObserver* observer) { 621 app_list::AppListViewDelegateObserver* observer) {
600 observers_.AddObserver(observer); 622 observers_.AddObserver(observer);
601 } 623 }
602 624
603 void AppListViewDelegate::RemoveObserver( 625 void AppListViewDelegate::RemoveObserver(
604 app_list::AppListViewDelegateObserver* observer) { 626 app_list::AppListViewDelegateObserver* observer) {
605 observers_.RemoveObserver(observer); 627 observers_.RemoveObserver(observer);
606 } 628 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698