| 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/download/download_request_limiter.h" | 5 #include "chrome/browser/download/download_request_limiter.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/stl_util.h" | 8 #include "base/stl_util.h" |
| 9 #include "chrome/browser/download/download_request_infobar_delegate.h" | 9 #include "chrome/browser/download/download_request_infobar_delegate.h" |
| 10 #include "chrome/browser/infobars/infobar_tab_helper.h" | 10 #include "chrome/browser/infobars/infobar_tab_helper.h" |
| (...skipping 19 matching lines...) Expand all Loading... |
| 30 DownloadRequestLimiter::TabDownloadState::TabDownloadState( | 30 DownloadRequestLimiter::TabDownloadState::TabDownloadState( |
| 31 DownloadRequestLimiter* host, | 31 DownloadRequestLimiter* host, |
| 32 NavigationController* controller, | 32 NavigationController* controller, |
| 33 NavigationController* originating_controller) | 33 NavigationController* originating_controller) |
| 34 : host_(host), | 34 : host_(host), |
| 35 controller_(controller), | 35 controller_(controller), |
| 36 status_(DownloadRequestLimiter::ALLOW_ONE_DOWNLOAD), | 36 status_(DownloadRequestLimiter::ALLOW_ONE_DOWNLOAD), |
| 37 download_count_(0), | 37 download_count_(0), |
| 38 infobar_(NULL) { | 38 infobar_(NULL) { |
| 39 content::Source<NavigationController> notification_source(controller); | 39 content::Source<NavigationController> notification_source(controller); |
| 40 content::Source<content::WebContents> web_contents_source( |
| 41 controller->GetWebContents()); |
| 40 registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_PENDING, | 42 registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_PENDING, |
| 41 notification_source); | 43 notification_source); |
| 42 registrar_.Add(this, content::NOTIFICATION_TAB_CLOSED, notification_source); | 44 registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED, |
| 45 web_contents_source); |
| 43 | 46 |
| 44 NavigationEntry* active_entry = originating_controller ? | 47 NavigationEntry* active_entry = originating_controller ? |
| 45 originating_controller->GetActiveEntry() : controller->GetActiveEntry(); | 48 originating_controller->GetActiveEntry() : controller->GetActiveEntry(); |
| 46 if (active_entry) | 49 if (active_entry) |
| 47 initial_page_host_ = active_entry->GetURL().host(); | 50 initial_page_host_ = active_entry->GetURL().host(); |
| 48 } | 51 } |
| 49 | 52 |
| 50 DownloadRequestLimiter::TabDownloadState::~TabDownloadState() { | 53 DownloadRequestLimiter::TabDownloadState::~TabDownloadState() { |
| 51 // We should only be destroyed after the callbacks have been notified. | 54 // We should only be destroyed after the callbacks have been notified. |
| 52 DCHECK(callbacks_.empty()); | 55 DCHECK(callbacks_.empty()); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 94 } | 97 } |
| 95 | 98 |
| 96 void DownloadRequestLimiter::TabDownloadState::Accept() { | 99 void DownloadRequestLimiter::TabDownloadState::Accept() { |
| 97 NotifyCallbacks(true); | 100 NotifyCallbacks(true); |
| 98 } | 101 } |
| 99 | 102 |
| 100 void DownloadRequestLimiter::TabDownloadState::Observe( | 103 void DownloadRequestLimiter::TabDownloadState::Observe( |
| 101 int type, | 104 int type, |
| 102 const content::NotificationSource& source, | 105 const content::NotificationSource& source, |
| 103 const content::NotificationDetails& details) { | 106 const content::NotificationDetails& details) { |
| 104 if ((type != content::NOTIFICATION_NAV_ENTRY_PENDING && | 107 if (type != content::NOTIFICATION_NAV_ENTRY_PENDING && |
| 105 type != content::NOTIFICATION_TAB_CLOSED) || | 108 type != content::NOTIFICATION_WEB_CONTENTS_DESTROYED) { |
| 109 NOTREACHED(); |
| 110 return; |
| 111 } |
| 112 if (type == content::NOTIFICATION_NAV_ENTRY_PENDING && |
| 106 content::Source<NavigationController>(source).ptr() != controller_) { | 113 content::Source<NavigationController>(source).ptr() != controller_) { |
| 107 NOTREACHED(); | 114 NOTREACHED(); |
| 108 return; | 115 return; |
| 109 } | 116 } |
| 117 if (type == content::NOTIFICATION_WEB_CONTENTS_DESTROYED && |
| 118 &content::Source<content::WebContents>(source).ptr()-> |
| 119 GetController() != controller_) { |
| 120 NOTREACHED(); |
| 121 return; |
| 122 } |
| 110 | 123 |
| 111 switch (type) { | 124 switch (type) { |
| 112 case content::NOTIFICATION_NAV_ENTRY_PENDING: { | 125 case content::NOTIFICATION_NAV_ENTRY_PENDING: { |
| 113 // NOTE: resetting state on a pending navigate isn't ideal. In particular | 126 // NOTE: resetting state on a pending navigate isn't ideal. In particular |
| 114 // it is possible that queued up downloads for the page before the | 127 // it is possible that queued up downloads for the page before the |
| 115 // pending navigate will be delivered to us after we process this | 128 // pending navigate will be delivered to us after we process this |
| 116 // request. If this happens we may let a download through that we | 129 // request. If this happens we may let a download through that we |
| 117 // shouldn't have. But this is rather rare, and it is difficult to get | 130 // shouldn't have. But this is rather rare, and it is difficult to get |
| 118 // 100% right, so we don't deal with it. | 131 // 100% right, so we don't deal with it. |
| 119 NavigationEntry* entry = controller_->GetPendingEntry(); | 132 NavigationEntry* entry = controller_->GetPendingEntry(); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 131 // reset the download state if the user is navigating to a different | 144 // reset the download state if the user is navigating to a different |
| 132 // host (or host is empty). | 145 // host (or host is empty). |
| 133 if (!initial_page_host_.empty() && !entry->GetURL().host().empty() && | 146 if (!initial_page_host_.empty() && !entry->GetURL().host().empty() && |
| 134 entry->GetURL().host() == initial_page_host_) { | 147 entry->GetURL().host() == initial_page_host_) { |
| 135 return; | 148 return; |
| 136 } | 149 } |
| 137 } | 150 } |
| 138 break; | 151 break; |
| 139 } | 152 } |
| 140 | 153 |
| 141 case content::NOTIFICATION_TAB_CLOSED: | 154 case content::NOTIFICATION_WEB_CONTENTS_DESTROYED: |
| 142 // Tab closed, no need to handle closing the dialog as it's owned by the | 155 // Tab closed, no need to handle closing the dialog as it's owned by the |
| 143 // TabContents, break so that we get deleted after switch. | 156 // TabContents, break so that we get deleted after switch. |
| 144 break; | 157 break; |
| 145 | 158 |
| 146 default: | 159 default: |
| 147 NOTREACHED(); | 160 NOTREACHED(); |
| 148 } | 161 } |
| 149 | 162 |
| 150 NotifyCallbacks(false); | 163 NotifyCallbacks(false); |
| 151 host_->Remove(this); | 164 host_->Remove(this); |
| (...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 336 | 349 |
| 337 void DownloadRequestLimiter::Remove(TabDownloadState* state) { | 350 void DownloadRequestLimiter::Remove(TabDownloadState* state) { |
| 338 DCHECK(ContainsKey(state_map_, state->controller())); | 351 DCHECK(ContainsKey(state_map_, state->controller())); |
| 339 state_map_.erase(state->controller()); | 352 state_map_.erase(state->controller()); |
| 340 delete state; | 353 delete state; |
| 341 } | 354 } |
| 342 | 355 |
| 343 // static | 356 // static |
| 344 DownloadRequestLimiter::TestingDelegate* DownloadRequestLimiter::delegate_ = | 357 DownloadRequestLimiter::TestingDelegate* DownloadRequestLimiter::delegate_ = |
| 345 NULL; | 358 NULL; |
| OLD | NEW |