| 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 |