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 "chrome/browser/ui/fast_unload_controller.h" | 5 #include "chrome/browser/ui/fast_unload_controller.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/message_loop/message_loop.h" | 8 #include "base/message_loop/message_loop.h" |
9 #include "chrome/browser/chrome_notification_types.h" | 9 #include "chrome/browser/chrome_notification_types.h" |
10 #include "chrome/browser/devtools/devtools_window.h" | 10 #include "chrome/browser/devtools/devtools_window.h" |
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
212 DevToolsWindow::NeedsToInterceptBeforeUnload(contents); | 212 DevToolsWindow::NeedsToInterceptBeforeUnload(contents); |
213 if (!ContainsKey(tabs_needing_unload_, contents) && | 213 if (!ContainsKey(tabs_needing_unload_, contents) && |
214 !ContainsKey(tabs_needing_unload_ack_, contents) && | 214 !ContainsKey(tabs_needing_unload_ack_, contents) && |
215 tab_needing_before_unload_ack_ != contents && | 215 tab_needing_before_unload_ack_ != contents && |
216 should_fire_beforeunload) | 216 should_fire_beforeunload) |
217 tabs_needing_before_unload_.insert(contents); | 217 tabs_needing_before_unload_.insert(contents); |
218 } | 218 } |
219 return !tabs_needing_before_unload_.empty(); | 219 return !tabs_needing_before_unload_.empty(); |
220 } | 220 } |
221 | 221 |
| 222 bool FastUnloadController::HasCompletedUnloadProcessing() const { |
| 223 return is_attempting_to_close_browser_ && |
| 224 tabs_needing_before_unload_.empty() && |
| 225 tab_needing_before_unload_ack_ == NULL && |
| 226 tabs_needing_unload_.empty() && |
| 227 tabs_needing_unload_ack_.empty(); |
| 228 } |
| 229 |
| 230 void FastUnloadController::CancelWindowClose() { |
| 231 // Closing of window can be canceled from a beforeunload handler. |
| 232 DCHECK(is_attempting_to_close_browser_); |
| 233 tabs_needing_before_unload_.clear(); |
| 234 if (tab_needing_before_unload_ack_ != NULL) { |
| 235 CoreTabHelper* core_tab_helper = |
| 236 CoreTabHelper::FromWebContents(tab_needing_before_unload_ack_); |
| 237 core_tab_helper->OnCloseCanceled(); |
| 238 DevToolsWindow::OnPageCloseCanceled(tab_needing_before_unload_ack_); |
| 239 tab_needing_before_unload_ack_ = NULL; |
| 240 } |
| 241 for (WebContentsSet::iterator it = tabs_needing_unload_.begin(); |
| 242 it != tabs_needing_unload_.end(); it++) { |
| 243 content::WebContents* contents = *it; |
| 244 |
| 245 CoreTabHelper* core_tab_helper = CoreTabHelper::FromWebContents(contents); |
| 246 core_tab_helper->OnCloseCanceled(); |
| 247 DevToolsWindow::OnPageCloseCanceled(contents); |
| 248 } |
| 249 tabs_needing_unload_.clear(); |
| 250 |
| 251 // No need to clear tabs_needing_unload_ack_. Those tabs are already detached. |
| 252 |
| 253 if (is_calling_before_unload_handlers()) { |
| 254 base::Callback<void(bool)> on_close_confirmed = on_close_confirmed_; |
| 255 on_close_confirmed_.Reset(); |
| 256 on_close_confirmed.Run(false); |
| 257 } |
| 258 |
| 259 is_attempting_to_close_browser_ = false; |
| 260 |
| 261 content::NotificationService::current()->Notify( |
| 262 chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED, |
| 263 content::Source<Browser>(browser_), |
| 264 content::NotificationService::NoDetails()); |
| 265 } |
| 266 |
222 //////////////////////////////////////////////////////////////////////////////// | 267 //////////////////////////////////////////////////////////////////////////////// |
223 // FastUnloadController, content::NotificationObserver implementation: | 268 // FastUnloadController, content::NotificationObserver implementation: |
224 | 269 |
225 void FastUnloadController::Observe( | 270 void FastUnloadController::Observe( |
226 int type, | 271 int type, |
227 const content::NotificationSource& source, | 272 const content::NotificationSource& source, |
228 const content::NotificationDetails& details) { | 273 const content::NotificationDetails& details) { |
229 switch (type) { | 274 switch (type) { |
230 case content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED: { | 275 case content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED: { |
231 registrar_.Remove(this, | 276 registrar_.Remove(this, |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
398 if (browser_->tab_strip_model()->empty()) { | 443 if (browser_->tab_strip_model()->empty()) { |
399 browser_->TabStripEmpty(); | 444 browser_->TabStripEmpty(); |
400 } else { | 445 } else { |
401 // There may be tabs if the last tab needing beforeunload crashed. | 446 // There may be tabs if the last tab needing beforeunload crashed. |
402 browser_->tab_strip_model()->CloseAllTabs(); | 447 browser_->tab_strip_model()->CloseAllTabs(); |
403 } | 448 } |
404 return; | 449 return; |
405 } | 450 } |
406 } | 451 } |
407 | 452 |
408 bool FastUnloadController::HasCompletedUnloadProcessing() const { | |
409 return is_attempting_to_close_browser_ && | |
410 tabs_needing_before_unload_.empty() && | |
411 tab_needing_before_unload_ack_ == NULL && | |
412 tabs_needing_unload_.empty() && | |
413 tabs_needing_unload_ack_.empty(); | |
414 } | |
415 | |
416 void FastUnloadController::CancelWindowClose() { | |
417 // Closing of window can be canceled from a beforeunload handler. | |
418 DCHECK(is_attempting_to_close_browser_); | |
419 tabs_needing_before_unload_.clear(); | |
420 if (tab_needing_before_unload_ack_ != NULL) { | |
421 CoreTabHelper* core_tab_helper = | |
422 CoreTabHelper::FromWebContents(tab_needing_before_unload_ack_); | |
423 core_tab_helper->OnCloseCanceled(); | |
424 DevToolsWindow::OnPageCloseCanceled(tab_needing_before_unload_ack_); | |
425 tab_needing_before_unload_ack_ = NULL; | |
426 } | |
427 for (WebContentsSet::iterator it = tabs_needing_unload_.begin(); | |
428 it != tabs_needing_unload_.end(); it++) { | |
429 content::WebContents* contents = *it; | |
430 | |
431 CoreTabHelper* core_tab_helper = CoreTabHelper::FromWebContents(contents); | |
432 core_tab_helper->OnCloseCanceled(); | |
433 DevToolsWindow::OnPageCloseCanceled(contents); | |
434 } | |
435 tabs_needing_unload_.clear(); | |
436 | |
437 // No need to clear tabs_needing_unload_ack_. Those tabs are already detached. | |
438 | |
439 if (is_calling_before_unload_handlers()) { | |
440 base::Callback<void(bool)> on_close_confirmed = on_close_confirmed_; | |
441 on_close_confirmed_.Reset(); | |
442 on_close_confirmed.Run(false); | |
443 } | |
444 | |
445 is_attempting_to_close_browser_ = false; | |
446 | |
447 content::NotificationService::current()->Notify( | |
448 chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED, | |
449 content::Source<Browser>(browser_), | |
450 content::NotificationService::NoDetails()); | |
451 } | |
452 | |
453 void FastUnloadController::ClearUnloadState(content::WebContents* contents) { | 453 void FastUnloadController::ClearUnloadState(content::WebContents* contents) { |
454 if (tabs_needing_unload_ack_.erase(contents) > 0) { | 454 if (tabs_needing_unload_ack_.erase(contents) > 0) { |
455 if (HasCompletedUnloadProcessing()) | 455 if (HasCompletedUnloadProcessing()) |
456 PostTaskForProcessPendingTabs(); | 456 PostTaskForProcessPendingTabs(); |
457 return; | 457 return; |
458 } | 458 } |
459 | 459 |
460 if (!is_attempting_to_close_browser_) | 460 if (!is_attempting_to_close_browser_) |
461 return; | 461 return; |
462 | 462 |
(...skipping 11 matching lines...) Expand all Loading... |
474 } | 474 } |
475 | 475 |
476 void FastUnloadController::PostTaskForProcessPendingTabs() { | 476 void FastUnloadController::PostTaskForProcessPendingTabs() { |
477 base::MessageLoop::current()->PostTask( | 477 base::MessageLoop::current()->PostTask( |
478 FROM_HERE, | 478 FROM_HERE, |
479 base::Bind(&FastUnloadController::ProcessPendingTabs, | 479 base::Bind(&FastUnloadController::ProcessPendingTabs, |
480 weak_factory_.GetWeakPtr())); | 480 weak_factory_.GetWeakPtr())); |
481 } | 481 } |
482 | 482 |
483 } // namespace chrome | 483 } // namespace chrome |
OLD | NEW |