| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "base/bind.h" | 5 #include "base/bind.h" |
| 6 #include "base/message_loop/message_loop.h" |
| 6 #include "chrome/browser/ui/views/app_list/app_list_shower.h" | 7 #include "chrome/browser/ui/views/app_list/app_list_shower.h" |
| 7 | 8 |
| 8 AppListShower::AppListShower(scoped_ptr<AppListViewFactory> factory, | 9 AppListShower::AppListShower(scoped_ptr<AppListViewFactory> factory, |
| 9 scoped_ptr<KeepAliveService> keep_alive) | 10 scoped_ptr<KeepAliveService> keep_alive) |
| 10 : factory_(factory.Pass()), | 11 : factory_(factory.Pass()), |
| 11 keep_alive_service_(keep_alive.Pass()), | 12 keep_alive_service_(keep_alive.Pass()), |
| 12 profile_(NULL), | 13 profile_(NULL), |
| 13 can_close_app_list_(true) { | 14 can_close_app_list_(true) { |
| 14 } | 15 } |
| 15 | 16 |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 65 void AppListShower::DismissAppList() { | 66 void AppListShower::DismissAppList() { |
| 66 if (view_ && can_close_app_list_) { | 67 if (view_ && can_close_app_list_) { |
| 67 view_->Hide(); | 68 view_->Hide(); |
| 68 keep_alive_service_->FreeKeepAlive(); | 69 keep_alive_service_->FreeKeepAlive(); |
| 69 } | 70 } |
| 70 } | 71 } |
| 71 | 72 |
| 72 void AppListShower::CloseAppList() { | 73 void AppListShower::CloseAppList() { |
| 73 view_.reset(); | 74 view_.reset(); |
| 74 profile_ = NULL; | 75 profile_ = NULL; |
| 76 |
| 77 // We may end up here as the result of the OS deleting the AppList's |
| 78 // widget (WidgetObserver::OnWidgetDestroyed). If this happens and there |
| 79 // are no browsers around then deleting the keep alive will result in |
| 80 // deleting the Widget again (by way of CloseAllSecondaryWidgets). When |
| 81 // the stack unravels we end up back in the Widget that was deleted and |
| 82 // crash. By delaying deletion of the keep alive we ensure the Widget has |
| 83 // correctly been destroyed before ending the keep alive so that |
| 84 // CloseAllSecondaryWidgets() won't attempt to delete the AppList's Widget |
| 85 // again. |
| 86 if (base::MessageLoop::current()) { // NULL in tests. |
| 87 base::MessageLoop::current()->PostTask(FROM_HERE, |
| 88 base::Bind(&KeepAliveService::FreeKeepAlive, |
| 89 base::Unretained(keep_alive_service_.get()))); |
| 90 return; |
| 91 } |
| 75 keep_alive_service_->FreeKeepAlive(); | 92 keep_alive_service_->FreeKeepAlive(); |
| 76 } | 93 } |
| 77 | 94 |
| 78 bool AppListShower::IsAppListVisible() const { | 95 bool AppListShower::IsAppListVisible() const { |
| 79 return view_ && view_->IsVisible(); | 96 return view_ && view_->IsVisible(); |
| 80 } | 97 } |
| 81 | 98 |
| 82 void AppListShower::WarmupForProfile(Profile* profile) { | 99 void AppListShower::WarmupForProfile(Profile* profile) { |
| 83 DCHECK(!profile_); | 100 DCHECK(!profile_); |
| 84 CreateViewForProfile(profile); | 101 CreateViewForProfile(profile); |
| 85 view_->Prerender(); | 102 view_->Prerender(); |
| 86 } | 103 } |
| 87 | 104 |
| 88 bool AppListShower::HasView() const { | 105 bool AppListShower::HasView() const { |
| 89 return !!view_; | 106 return !!view_; |
| 90 } | 107 } |
| OLD | NEW |