| OLD | NEW |
| 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/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.h" | 8 #include "base/message_loop.h" |
| 9 #include "chrome/browser/ui/browser.h" | 9 #include "chrome/browser/ui/browser.h" |
| 10 #include "chrome/browser/ui/browser_tabstrip.h" | 10 #include "chrome/browser/ui/browser_tabstrip.h" |
| 11 #include "chrome/browser/ui/tab_contents/core_tab_helper.h" | 11 #include "chrome/browser/ui/tab_contents/core_tab_helper.h" |
| 12 #include "chrome/browser/ui/tabs/tab_strip_model.h" | 12 #include "chrome/browser/ui/tabs/tab_strip_model.h" |
| 13 #include "chrome/browser/ui/tabs/tab_strip_model_delegate.h" | 13 #include "chrome/browser/ui/tabs/tab_strip_model_delegate.h" |
| 14 #include "chrome/common/chrome_notification_types.h" | 14 #include "chrome/common/chrome_notification_types.h" |
| 15 #include "content/public/browser/notification_service.h" | 15 #include "content/public/browser/notification_service.h" |
| 16 #include "content/public/browser/notification_source.h" | 16 #include "content/public/browser/notification_source.h" |
| 17 #include "content/public/browser/notification_types.h" | 17 #include "content/public/browser/notification_types.h" |
| 18 #include "content/public/browser/render_view_host.h" | 18 #include "content/public/browser/render_view_host.h" |
| 19 #include "content/public/browser/web_contents.h" | 19 #include "content/public/browser/web_contents.h" |
| 20 #include "content/public/browser/web_contents_delegate.h" | 20 #include "content/public/browser/web_contents_delegate.h" |
| 21 | 21 |
| 22 namespace chrome { | 22 namespace chrome { |
| 23 | 23 |
| 24 | 24 |
| 25 //////////////////////////////////////////////////////////////////////////////// | 25 //////////////////////////////////////////////////////////////////////////////// |
| 26 // DetachedWebContentsDelegate will delete web contents when they close. | 26 // DetachedWebContentsDelegate will delete web contents when they close. |
| 27 class UnloadController::DetachedWebContentsDelegate | 27 class FastUnloadController::DetachedWebContentsDelegate |
| 28 : public content::WebContentsDelegate { | 28 : public content::WebContentsDelegate { |
| 29 public: | 29 public: |
| 30 DetachedWebContentsDelegate() { } | 30 DetachedWebContentsDelegate() { } |
| 31 virtual ~DetachedWebContentsDelegate() { } | 31 virtual ~DetachedWebContentsDelegate() { } |
| 32 | 32 |
| 33 private: | 33 private: |
| 34 // WebContentsDelegate implementation. | 34 // WebContentsDelegate implementation. |
| 35 virtual bool ShouldSuppressDialogs() OVERRIDE { | 35 virtual bool ShouldSuppressDialogs() OVERRIDE { |
| 36 return true; // Return true so dialogs are suppressed. | 36 return true; // Return true so dialogs are suppressed. |
| 37 } | 37 } |
| 38 | 38 |
| 39 virtual void CloseContents(content::WebContents* source) OVERRIDE { | 39 virtual void CloseContents(content::WebContents* source) OVERRIDE { |
| 40 // Finished detached close. | 40 // Finished detached close. |
| 41 // UnloadController will observe | 41 // FastUnloadController will observe |
| 42 // |NOTIFICATION_WEB_CONTENTS_DISCONNECTED|. | 42 // |NOTIFICATION_WEB_CONTENTS_DISCONNECTED|. |
| 43 delete source; | 43 delete source; |
| 44 } | 44 } |
| 45 | 45 |
| 46 DISALLOW_COPY_AND_ASSIGN(DetachedWebContentsDelegate); | 46 DISALLOW_COPY_AND_ASSIGN(DetachedWebContentsDelegate); |
| 47 }; | 47 }; |
| 48 | 48 |
| 49 //////////////////////////////////////////////////////////////////////////////// | 49 //////////////////////////////////////////////////////////////////////////////// |
| 50 // UnloadController, public: | 50 // FastUnloadController, public: |
| 51 | 51 |
| 52 UnloadController::UnloadController(Browser* browser) | 52 FastUnloadController::FastUnloadController(Browser* browser) |
| 53 : browser_(browser), | 53 : browser_(browser), |
| 54 tab_needing_before_unload_ack_(NULL), | 54 tab_needing_before_unload_ack_(NULL), |
| 55 is_attempting_to_close_browser_(false), | 55 is_attempting_to_close_browser_(false), |
| 56 detached_delegate_(new DetachedWebContentsDelegate()), | 56 detached_delegate_(new DetachedWebContentsDelegate()), |
| 57 weak_factory_(this) { | 57 weak_factory_(this) { |
| 58 browser_->tab_strip_model()->AddObserver(this); | 58 browser_->tab_strip_model()->AddObserver(this); |
| 59 } | 59 } |
| 60 | 60 |
| 61 UnloadController::~UnloadController() { | 61 FastUnloadController::~FastUnloadController() { |
| 62 browser_->tab_strip_model()->RemoveObserver(this); | 62 browser_->tab_strip_model()->RemoveObserver(this); |
| 63 } | 63 } |
| 64 | 64 |
| 65 bool UnloadController::CanCloseContents(content::WebContents* contents) { | 65 bool FastUnloadController::CanCloseContents(content::WebContents* contents) { |
| 66 // Don't try to close the tab when the whole browser is being closed, since | 66 // Don't try to close the tab when the whole browser is being closed, since |
| 67 // that avoids the fast shutdown path where we just kill all the renderers. | 67 // that avoids the fast shutdown path where we just kill all the renderers. |
| 68 return !is_attempting_to_close_browser_; | 68 return !is_attempting_to_close_browser_; |
| 69 } | 69 } |
| 70 | 70 |
| 71 bool UnloadController::BeforeUnloadFired(content::WebContents* contents, | 71 bool FastUnloadController::BeforeUnloadFired(content::WebContents* contents, |
| 72 bool proceed) { | 72 bool proceed) { |
| 73 if (!is_attempting_to_close_browser_) { | 73 if (!is_attempting_to_close_browser_) { |
| 74 if (!proceed) { | 74 if (!proceed) { |
| 75 contents->SetClosedByUserGesture(false); | 75 contents->SetClosedByUserGesture(false); |
| 76 } else { | 76 } else { |
| 77 // No more dialogs are possible, so remove the tab and finish | 77 // No more dialogs are possible, so remove the tab and finish |
| 78 // running unload listeners asynchrounously. | 78 // running unload listeners asynchrounously. |
| 79 browser_->tab_strip_model()->delegate()->CreateHistoricalTab(contents); | 79 browser_->tab_strip_model()->delegate()->CreateHistoricalTab(contents); |
| 80 DetachWebContents(contents); | 80 DetachWebContents(contents); |
| 81 } | 81 } |
| 82 return proceed; | 82 return proceed; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 95 ProcessPendingTabs(); | 95 ProcessPendingTabs(); |
| 96 // We want to handle firing the unload event ourselves since we want to | 96 // We want to handle firing the unload event ourselves since we want to |
| 97 // fire all the beforeunload events before attempting to fire the unload | 97 // fire all the beforeunload events before attempting to fire the unload |
| 98 // events should the user cancel closing the browser. | 98 // events should the user cancel closing the browser. |
| 99 return false; | 99 return false; |
| 100 } | 100 } |
| 101 | 101 |
| 102 return true; | 102 return true; |
| 103 } | 103 } |
| 104 | 104 |
| 105 bool UnloadController::ShouldCloseWindow() { | 105 bool FastUnloadController::ShouldCloseWindow() { |
| 106 if (HasCompletedUnloadProcessing()) | 106 if (HasCompletedUnloadProcessing()) |
| 107 return true; | 107 return true; |
| 108 | 108 |
| 109 is_attempting_to_close_browser_ = true; | 109 is_attempting_to_close_browser_ = true; |
| 110 | 110 |
| 111 if (!TabsNeedBeforeUnloadFired()) | 111 if (!TabsNeedBeforeUnloadFired()) |
| 112 return true; | 112 return true; |
| 113 | 113 |
| 114 ProcessPendingTabs(); | 114 ProcessPendingTabs(); |
| 115 return false; | 115 return false; |
| 116 } | 116 } |
| 117 | 117 |
| 118 bool UnloadController::TabsNeedBeforeUnloadFired() { | 118 bool FastUnloadController::TabsNeedBeforeUnloadFired() { |
| 119 if (!tabs_needing_before_unload_.empty() || | 119 if (!tabs_needing_before_unload_.empty() || |
| 120 tab_needing_before_unload_ack_ != NULL) | 120 tab_needing_before_unload_ack_ != NULL) |
| 121 return true; | 121 return true; |
| 122 | 122 |
| 123 if (!tabs_needing_unload_.empty()) | 123 if (!tabs_needing_unload_.empty()) |
| 124 return false; | 124 return false; |
| 125 | 125 |
| 126 for (int i = 0; i < browser_->tab_strip_model()->count(); ++i) { | 126 for (int i = 0; i < browser_->tab_strip_model()->count(); ++i) { |
| 127 content::WebContents* contents = | 127 content::WebContents* contents = |
| 128 browser_->tab_strip_model()->GetWebContentsAt(i); | 128 browser_->tab_strip_model()->GetWebContentsAt(i); |
| 129 if (contents->NeedToFireBeforeUnload()) | 129 if (contents->NeedToFireBeforeUnload()) |
| 130 tabs_needing_before_unload_.insert(contents); | 130 tabs_needing_before_unload_.insert(contents); |
| 131 } | 131 } |
| 132 return !tabs_needing_before_unload_.empty(); | 132 return !tabs_needing_before_unload_.empty(); |
| 133 } | 133 } |
| 134 | 134 |
| 135 //////////////////////////////////////////////////////////////////////////////// | 135 //////////////////////////////////////////////////////////////////////////////// |
| 136 // UnloadController, content::NotificationObserver implementation: | 136 // FastUnloadController, content::NotificationObserver implementation: |
| 137 | 137 |
| 138 void UnloadController::Observe(int type, | 138 void FastUnloadController::Observe( |
| 139 const content::NotificationSource& source, | 139 int type, |
| 140 const content::NotificationDetails& details) { | 140 const content::NotificationSource& source, |
| 141 const content::NotificationDetails& details) { |
| 141 switch (type) { | 142 switch (type) { |
| 142 case content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED: { | 143 case content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED: { |
| 143 registrar_.Remove(this, | 144 registrar_.Remove(this, |
| 144 content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED, | 145 content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED, |
| 145 source); | 146 source); |
| 146 content::WebContents* contents = | 147 content::WebContents* contents = |
| 147 content::Source<content::WebContents>(source).ptr(); | 148 content::Source<content::WebContents>(source).ptr(); |
| 148 ClearUnloadState(contents); | 149 ClearUnloadState(contents); |
| 149 break; | 150 break; |
| 150 } | 151 } |
| 151 default: | 152 default: |
| 152 NOTREACHED() << "Got a notification we didn't register for."; | 153 NOTREACHED() << "Got a notification we didn't register for."; |
| 153 } | 154 } |
| 154 } | 155 } |
| 155 | 156 |
| 156 //////////////////////////////////////////////////////////////////////////////// | 157 //////////////////////////////////////////////////////////////////////////////// |
| 157 // UnloadController, TabStripModelObserver implementation: | 158 // FastUnloadController, TabStripModelObserver implementation: |
| 158 | 159 |
| 159 void UnloadController::TabInsertedAt(content::WebContents* contents, | 160 void FastUnloadController::TabInsertedAt(content::WebContents* contents, |
| 160 int index, | 161 int index, |
| 161 bool foreground) { | 162 bool foreground) { |
| 162 TabAttachedImpl(contents); | 163 TabAttachedImpl(contents); |
| 163 } | 164 } |
| 164 | 165 |
| 165 void UnloadController::TabDetachedAt(content::WebContents* contents, | 166 void FastUnloadController::TabDetachedAt(content::WebContents* contents, |
| 166 int index) { | 167 int index) { |
| 167 TabDetachedImpl(contents); | 168 TabDetachedImpl(contents); |
| 168 } | 169 } |
| 169 | 170 |
| 170 void UnloadController::TabReplacedAt(TabStripModel* tab_strip_model, | 171 void FastUnloadController::TabReplacedAt(TabStripModel* tab_strip_model, |
| 171 content::WebContents* old_contents, | 172 content::WebContents* old_contents, |
| 172 content::WebContents* new_contents, | 173 content::WebContents* new_contents, |
| 173 int index) { | 174 int index) { |
| 174 TabDetachedImpl(old_contents); | 175 TabDetachedImpl(old_contents); |
| 175 TabAttachedImpl(new_contents); | 176 TabAttachedImpl(new_contents); |
| 176 } | 177 } |
| 177 | 178 |
| 178 void UnloadController::TabStripEmpty() { | 179 void FastUnloadController::TabStripEmpty() { |
| 179 // Set is_attempting_to_close_browser_ here, so that extensions, etc, do not | 180 // Set is_attempting_to_close_browser_ here, so that extensions, etc, do not |
| 180 // attempt to add tabs to the browser before it closes. | 181 // attempt to add tabs to the browser before it closes. |
| 181 is_attempting_to_close_browser_ = true; | 182 is_attempting_to_close_browser_ = true; |
| 182 } | 183 } |
| 183 | 184 |
| 184 //////////////////////////////////////////////////////////////////////////////// | 185 //////////////////////////////////////////////////////////////////////////////// |
| 185 // UnloadController, private: | 186 // FastUnloadController, private: |
| 186 | 187 |
| 187 void UnloadController::TabAttachedImpl(content::WebContents* contents) { | 188 void FastUnloadController::TabAttachedImpl(content::WebContents* contents) { |
| 188 // If the tab crashes in the beforeunload or unload handler, it won't be | 189 // If the tab crashes in the beforeunload or unload handler, it won't be |
| 189 // able to ack. But we know we can close it. | 190 // able to ack. But we know we can close it. |
| 190 registrar_.Add( | 191 registrar_.Add( |
| 191 this, | 192 this, |
| 192 content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED, | 193 content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED, |
| 193 content::Source<content::WebContents>(contents)); | 194 content::Source<content::WebContents>(contents)); |
| 194 } | 195 } |
| 195 | 196 |
| 196 void UnloadController::TabDetachedImpl(content::WebContents* contents) { | 197 void FastUnloadController::TabDetachedImpl(content::WebContents* contents) { |
| 197 if (tabs_needing_unload_ack_.find(contents) != | 198 if (tabs_needing_unload_ack_.find(contents) != |
| 198 tabs_needing_unload_ack_.end()) { | 199 tabs_needing_unload_ack_.end()) { |
| 199 // Tab needs unload to complete. | 200 // Tab needs unload to complete. |
| 200 // It will send |NOTIFICATION_WEB_CONTENTS_DISCONNECTED| when done. | 201 // It will send |NOTIFICATION_WEB_CONTENTS_DISCONNECTED| when done. |
| 201 return; | 202 return; |
| 202 } | 203 } |
| 203 | 204 |
| 204 // If WEB_CONTENTS_DISCONNECTED was received then the notification may have | 205 // If WEB_CONTENTS_DISCONNECTED was received then the notification may have |
| 205 // already been unregistered. | 206 // already been unregistered. |
| 206 const content::NotificationSource& source = | 207 const content::NotificationSource& source = |
| 207 content::Source<content::WebContents>(contents); | 208 content::Source<content::WebContents>(contents); |
| 208 if (registrar_.IsRegistered(this, | 209 if (registrar_.IsRegistered(this, |
| 209 content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED, | 210 content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED, |
| 210 source)) { | 211 source)) { |
| 211 registrar_.Remove(this, | 212 registrar_.Remove(this, |
| 212 content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED, | 213 content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED, |
| 213 source); | 214 source); |
| 214 } | 215 } |
| 215 | 216 |
| 216 if (is_attempting_to_close_browser_) | 217 if (is_attempting_to_close_browser_) |
| 217 ClearUnloadState(contents); | 218 ClearUnloadState(contents); |
| 218 } | 219 } |
| 219 | 220 |
| 220 bool UnloadController::DetachWebContents(content::WebContents* contents) { | 221 bool FastUnloadController::DetachWebContents(content::WebContents* contents) { |
| 221 int index = browser_->tab_strip_model()->GetIndexOfWebContents(contents); | 222 int index = browser_->tab_strip_model()->GetIndexOfWebContents(contents); |
| 222 if (index != TabStripModel::kNoTab && | 223 if (index != TabStripModel::kNoTab && |
| 223 contents->NeedToFireBeforeUnload()) { | 224 contents->NeedToFireBeforeUnload()) { |
| 224 tabs_needing_unload_ack_.insert(contents); | 225 tabs_needing_unload_ack_.insert(contents); |
| 225 browser_->tab_strip_model()->DetachWebContentsAt(index); | 226 browser_->tab_strip_model()->DetachWebContentsAt(index); |
| 226 contents->SetDelegate(detached_delegate_.get()); | 227 contents->SetDelegate(detached_delegate_.get()); |
| 227 CoreTabHelper* core_tab_helper = CoreTabHelper::FromWebContents(contents); | 228 CoreTabHelper* core_tab_helper = CoreTabHelper::FromWebContents(contents); |
| 228 core_tab_helper->OnUnloadDetachedStarted(); | 229 core_tab_helper->OnUnloadDetachedStarted(); |
| 229 return true; | 230 return true; |
| 230 } | 231 } |
| 231 return false; | 232 return false; |
| 232 } | 233 } |
| 233 | 234 |
| 234 void UnloadController::ProcessPendingTabs() { | 235 void FastUnloadController::ProcessPendingTabs() { |
| 235 if (!is_attempting_to_close_browser_) { | 236 if (!is_attempting_to_close_browser_) { |
| 236 // Because we might invoke this after a delay it's possible for the value of | 237 // Because we might invoke this after a delay it's possible for the value of |
| 237 // is_attempting_to_close_browser_ to have changed since we scheduled the | 238 // is_attempting_to_close_browser_ to have changed since we scheduled the |
| 238 // task. | 239 // task. |
| 239 return; | 240 return; |
| 240 } | 241 } |
| 241 | 242 |
| 242 if (tab_needing_before_unload_ack_ != NULL) { | 243 if (tab_needing_before_unload_ack_ != NULL) { |
| 243 // Wait for |BeforeUnloadFired| before proceeding. | 244 // Wait for |BeforeUnloadFired| before proceeding. |
| 244 return; | 245 return; |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 301 if (browser_->tab_strip_model()->empty()) { | 302 if (browser_->tab_strip_model()->empty()) { |
| 302 browser_->TabStripEmpty(); | 303 browser_->TabStripEmpty(); |
| 303 } else { | 304 } else { |
| 304 // There may be tabs if the last tab needing beforeunload crashed. | 305 // There may be tabs if the last tab needing beforeunload crashed. |
| 305 browser_->tab_strip_model()->CloseAllTabs(); | 306 browser_->tab_strip_model()->CloseAllTabs(); |
| 306 } | 307 } |
| 307 return; | 308 return; |
| 308 } | 309 } |
| 309 } | 310 } |
| 310 | 311 |
| 311 bool UnloadController::HasCompletedUnloadProcessing() const { | 312 bool FastUnloadController::HasCompletedUnloadProcessing() const { |
| 312 return is_attempting_to_close_browser_ && | 313 return is_attempting_to_close_browser_ && |
| 313 tabs_needing_before_unload_.empty() && | 314 tabs_needing_before_unload_.empty() && |
| 314 tab_needing_before_unload_ack_ == NULL && | 315 tab_needing_before_unload_ack_ == NULL && |
| 315 tabs_needing_unload_.empty() && | 316 tabs_needing_unload_.empty() && |
| 316 tabs_needing_unload_ack_.empty(); | 317 tabs_needing_unload_ack_.empty(); |
| 317 } | 318 } |
| 318 | 319 |
| 319 void UnloadController::CancelWindowClose() { | 320 void FastUnloadController::CancelWindowClose() { |
| 320 // Closing of window can be canceled from a beforeunload handler. | 321 // Closing of window can be canceled from a beforeunload handler. |
| 321 DCHECK(is_attempting_to_close_browser_); | 322 DCHECK(is_attempting_to_close_browser_); |
| 322 tabs_needing_before_unload_.clear(); | 323 tabs_needing_before_unload_.clear(); |
| 323 if (tab_needing_before_unload_ack_ != NULL) { | 324 if (tab_needing_before_unload_ack_ != NULL) { |
| 324 | 325 |
| 325 CoreTabHelper* core_tab_helper = | 326 CoreTabHelper* core_tab_helper = |
| 326 CoreTabHelper::FromWebContents(tab_needing_before_unload_ack_); | 327 CoreTabHelper::FromWebContents(tab_needing_before_unload_ack_); |
| 327 core_tab_helper->OnCloseCanceled(); | 328 core_tab_helper->OnCloseCanceled(); |
| 328 tab_needing_before_unload_ack_ = NULL; | 329 tab_needing_before_unload_ack_ = NULL; |
| 329 } | 330 } |
| 330 for (WebContentsSet::iterator it = tabs_needing_unload_.begin(); | 331 for (WebContentsSet::iterator it = tabs_needing_unload_.begin(); |
| 331 it != tabs_needing_unload_.end(); it++) { | 332 it != tabs_needing_unload_.end(); it++) { |
| 332 content::WebContents* contents = *it; | 333 content::WebContents* contents = *it; |
| 333 | 334 |
| 334 CoreTabHelper* core_tab_helper = CoreTabHelper::FromWebContents(contents); | 335 CoreTabHelper* core_tab_helper = CoreTabHelper::FromWebContents(contents); |
| 335 core_tab_helper->OnCloseCanceled(); | 336 core_tab_helper->OnCloseCanceled(); |
| 336 } | 337 } |
| 337 tabs_needing_unload_.clear(); | 338 tabs_needing_unload_.clear(); |
| 338 | 339 |
| 339 // No need to clear tabs_needing_unload_ack_. Those tabs are already detached. | 340 // No need to clear tabs_needing_unload_ack_. Those tabs are already detached. |
| 340 | 341 |
| 341 is_attempting_to_close_browser_ = false; | 342 is_attempting_to_close_browser_ = false; |
| 342 | 343 |
| 343 content::NotificationService::current()->Notify( | 344 content::NotificationService::current()->Notify( |
| 344 chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED, | 345 chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED, |
| 345 content::Source<Browser>(browser_), | 346 content::Source<Browser>(browser_), |
| 346 content::NotificationService::NoDetails()); | 347 content::NotificationService::NoDetails()); |
| 347 } | 348 } |
| 348 | 349 |
| 349 void UnloadController::ClearUnloadState(content::WebContents* contents) { | 350 void FastUnloadController::ClearUnloadState(content::WebContents* contents) { |
| 350 if (tabs_needing_unload_ack_.erase(contents) > 0) { | 351 if (tabs_needing_unload_ack_.erase(contents) > 0) { |
| 351 if (HasCompletedUnloadProcessing()) | 352 if (HasCompletedUnloadProcessing()) |
| 352 PostTaskForProcessPendingTabs(); | 353 PostTaskForProcessPendingTabs(); |
| 353 return; | 354 return; |
| 354 } | 355 } |
| 355 | 356 |
| 356 if (!is_attempting_to_close_browser_) | 357 if (!is_attempting_to_close_browser_) |
| 357 return; | 358 return; |
| 358 | 359 |
| 359 if (tab_needing_before_unload_ack_ == contents) { | 360 if (tab_needing_before_unload_ack_ == contents) { |
| 360 tab_needing_before_unload_ack_ = NULL; | 361 tab_needing_before_unload_ack_ = NULL; |
| 361 PostTaskForProcessPendingTabs(); | 362 PostTaskForProcessPendingTabs(); |
| 362 return; | 363 return; |
| 363 } | 364 } |
| 364 | 365 |
| 365 if (tabs_needing_before_unload_.erase(contents) > 0 || | 366 if (tabs_needing_before_unload_.erase(contents) > 0 || |
| 366 tabs_needing_unload_.erase(contents) > 0) { | 367 tabs_needing_unload_.erase(contents) > 0) { |
| 367 if (tab_needing_before_unload_ack_ == NULL) | 368 if (tab_needing_before_unload_ack_ == NULL) |
| 368 PostTaskForProcessPendingTabs(); | 369 PostTaskForProcessPendingTabs(); |
| 369 } | 370 } |
| 370 } | 371 } |
| 371 | 372 |
| 372 void UnloadController::PostTaskForProcessPendingTabs() { | 373 void FastUnloadController::PostTaskForProcessPendingTabs() { |
| 373 base::MessageLoop::current()->PostTask( | 374 base::MessageLoop::current()->PostTask( |
| 374 FROM_HERE, | 375 FROM_HERE, |
| 375 base::Bind(&UnloadController::ProcessPendingTabs, | 376 base::Bind(&FastUnloadController::ProcessPendingTabs, |
| 376 weak_factory_.GetWeakPtr())); | 377 weak_factory_.GetWeakPtr())); |
| 377 } | 378 } |
| 378 | 379 |
| 379 } // namespace chrome | 380 } // namespace chrome |
| OLD | NEW |