| 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 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 121 : host_(NULL), | 121 : host_(NULL), |
| 122 status_(DownloadRequestLimiter::ALLOW_ONE_DOWNLOAD), | 122 status_(DownloadRequestLimiter::ALLOW_ONE_DOWNLOAD), |
| 123 download_count_(0), | 123 download_count_(0), |
| 124 infobar_(NULL) { | 124 infobar_(NULL) { |
| 125 } | 125 } |
| 126 | 126 |
| 127 void DownloadRequestLimiter::TabDownloadState::Observe( | 127 void DownloadRequestLimiter::TabDownloadState::Observe( |
| 128 int type, | 128 int type, |
| 129 const content::NotificationSource& source, | 129 const content::NotificationSource& source, |
| 130 const content::NotificationDetails& details) { | 130 const content::NotificationDetails& details) { |
| 131 if (type != content::NOTIFICATION_NAV_ENTRY_PENDING && | |
| 132 type != content::NOTIFICATION_WEB_CONTENTS_DESTROYED) { | |
| 133 NOTREACHED(); | |
| 134 return; | |
| 135 } | |
| 136 content::NavigationController* controller = &web_contents()->GetController(); | 131 content::NavigationController* controller = &web_contents()->GetController(); |
| 137 if (type == content::NOTIFICATION_NAV_ENTRY_PENDING && | 132 if (type == content::NOTIFICATION_NAV_ENTRY_PENDING) { |
| 138 content::Source<NavigationController>(source).ptr() != controller) { | 133 DCHECK_EQ(controller, content::Source<NavigationController>(source).ptr()); |
| 139 NOTREACHED(); | |
| 140 return; | |
| 141 } | |
| 142 if (type == content::NOTIFICATION_WEB_CONTENTS_DESTROYED && | |
| 143 &content::Source<content::WebContents>(source).ptr()-> | |
| 144 GetController() != controller) { | |
| 145 NOTREACHED(); | |
| 146 return; | |
| 147 } | |
| 148 | 134 |
| 149 switch (type) { | 135 // NOTE: Resetting state on a pending navigate isn't ideal. In particular it |
| 150 case content::NOTIFICATION_NAV_ENTRY_PENDING: { | 136 // is possible that queued up downloads for the page before the pending |
| 151 // NOTE: resetting state on a pending navigate isn't ideal. In particular | 137 // navigation will be delivered to us after we process this request. If this |
| 152 // it is possible that queued up downloads for the page before the | 138 // happens we may let a download through that we shouldn't have. But this is |
| 153 // pending navigate will be delivered to us after we process this | 139 // rather rare, and it is difficult to get 100% right, so we don't deal with |
| 154 // request. If this happens we may let a download through that we | 140 // it. |
| 155 // shouldn't have. But this is rather rare, and it is difficult to get | 141 NavigationEntry* entry = controller->GetPendingEntry(); |
| 156 // 100% right, so we don't deal with it. | 142 if (!entry) |
| 157 NavigationEntry* entry = controller->GetPendingEntry(); | 143 return; |
| 158 if (!entry) | 144 |
| 145 // Redirects don't count. |
| 146 if (content::PageTransitionIsRedirect(entry->GetTransitionType())) |
| 147 return; |
| 148 |
| 149 if (status_ == DownloadRequestLimiter::ALLOW_ALL_DOWNLOADS || |
| 150 status_ == DownloadRequestLimiter::DOWNLOADS_NOT_ALLOWED) { |
| 151 // User has either allowed all downloads or canceled all downloads. Only |
| 152 // reset the download state if the user is navigating to a different host |
| 153 // (or host is empty). |
| 154 if (!initial_page_host_.empty() && !entry->GetURL().host().empty() && |
| 155 entry->GetURL().host() == initial_page_host_) |
| 159 return; | 156 return; |
| 160 | |
| 161 if (content::PageTransitionIsRedirect(entry->GetTransitionType())) { | |
| 162 // Redirects don't count. | |
| 163 return; | |
| 164 } | |
| 165 | |
| 166 if (status_ == DownloadRequestLimiter::ALLOW_ALL_DOWNLOADS || | |
| 167 status_ == DownloadRequestLimiter::DOWNLOADS_NOT_ALLOWED) { | |
| 168 // User has either allowed all downloads or canceled all downloads. Only | |
| 169 // reset the download state if the user is navigating to a different | |
| 170 // host (or host is empty). | |
| 171 if (!initial_page_host_.empty() && !entry->GetURL().host().empty() && | |
| 172 entry->GetURL().host() == initial_page_host_) { | |
| 173 return; | |
| 174 } | |
| 175 } | |
| 176 break; | |
| 177 } | 157 } |
| 178 | 158 } else { |
| 179 case content::NOTIFICATION_WEB_CONTENTS_DESTROYED: | 159 DCHECK_EQ(content::NOTIFICATION_WEB_CONTENTS_DESTROYED, type); |
| 180 // Tab closed, no need to handle closing the dialog as it's owned by the | 160 DCHECK_EQ(controller, |
| 181 // WebContents, break so that we get deleted after switch. | 161 &content::Source<content::WebContents>(source)->GetController()); |
| 182 break; | 162 // Tab closed, no need to handle closing the dialog as it's owned by the |
| 183 | 163 // WebContents. |
| 184 default: | |
| 185 NOTREACHED(); | |
| 186 } | 164 } |
| 187 | 165 |
| 188 NotifyCallbacks(false); | 166 NotifyCallbacks(false); |
| 189 host_->Remove(this); | 167 host_->Remove(this); |
| 190 } | 168 } |
| 191 | 169 |
| 192 void DownloadRequestLimiter::TabDownloadState::NotifyCallbacks(bool allow) { | 170 void DownloadRequestLimiter::TabDownloadState::NotifyCallbacks(bool allow) { |
| 193 set_download_status(allow ? | 171 set_download_status(allow ? |
| 194 DownloadRequestLimiter::ALLOW_ALL_DOWNLOADS : | 172 DownloadRequestLimiter::ALLOW_ALL_DOWNLOADS : |
| 195 DownloadRequestLimiter::DOWNLOADS_NOT_ALLOWED); | 173 DownloadRequestLimiter::DOWNLOADS_NOT_ALLOWED); |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 371 | 349 |
| 372 void DownloadRequestLimiter::Remove(TabDownloadState* state) { | 350 void DownloadRequestLimiter::Remove(TabDownloadState* state) { |
| 373 DCHECK(ContainsKey(state_map_, state->web_contents())); | 351 DCHECK(ContainsKey(state_map_, state->web_contents())); |
| 374 state_map_.erase(state->web_contents()); | 352 state_map_.erase(state->web_contents()); |
| 375 delete state; | 353 delete state; |
| 376 } | 354 } |
| 377 | 355 |
| 378 // static | 356 // static |
| 379 DownloadRequestLimiter::TestingDelegate* DownloadRequestLimiter::delegate_ = | 357 DownloadRequestLimiter::TestingDelegate* DownloadRequestLimiter::delegate_ = |
| 380 NULL; | 358 NULL; |
| OLD | NEW |