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
3 // found in the LICENSE file.
5 #include "chrome/browser/download/download_resource_throttle.h"
8 #include "chrome/browser/download/download_stats.h"
9 #include "content/public/browser/browser_thread.h"
10 #include "content/public/browser/resource_controller.h"
12 #if defined(OS_ANDROID)
13 #include "content/public/browser/android/download_controller_android.h"
14 #include "content/public/browser/render_view_host.h"
16 using content::DownloadControllerAndroid
;
19 using content::BrowserThread
;
23 void OnCanDownloadDecided(base::WeakPtr
<DownloadResourceThrottle
> throttle
,
25 BrowserThread::PostTask(
26 BrowserThread::IO
, FROM_HERE
,
27 base::Bind(&DownloadResourceThrottle::ContinueDownload
, throttle
, allow
));
31 scoped_ptr
<DownloadResourceThrottle::DownloadRequestInfo
> info
) {
32 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
33 info
->limiter
->CanDownload(info
->render_process_id
, info
->render_view_id
,
34 info
->url
, info
->request_method
,
35 info
->continue_callback
);
38 #if defined(OS_ANDROID)
39 void OnAcquireFileAccessPermissionDone(
40 scoped_ptr
<DownloadResourceThrottle::DownloadRequestInfo
> info
,
42 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
44 CanDownload(info
.Pass());
46 info
->continue_callback
.Run(false);
50 void CanDownloadOnUIThread(
51 scoped_ptr
<DownloadResourceThrottle::DownloadRequestInfo
> info
) {
52 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
53 #if defined(OS_ANDROID)
54 int process_id
= info
->render_process_id
;
55 int render_view_id
= info
->render_view_id
;
56 content::DownloadControllerAndroid::Get()->AcquireFileAccessPermission(
57 process_id
, render_view_id
, base::Bind(&OnAcquireFileAccessPermissionDone
,
58 base::Passed(info
.Pass())));
60 CanDownload(info
.Pass());
66 DownloadResourceThrottle::DownloadRequestInfo::DownloadRequestInfo(
67 scoped_refptr
<DownloadRequestLimiter
> limiter
,
68 int render_process_id
,
71 const std::string
& request_method
,
72 const DownloadRequestLimiter::Callback
& continue_callback
)
74 render_process_id(render_process_id
),
75 render_view_id(render_view_id
),
77 request_method(request_method
),
78 continue_callback(continue_callback
) {}
80 DownloadResourceThrottle::DownloadRequestInfo::~DownloadRequestInfo() {}
82 DownloadResourceThrottle::DownloadResourceThrottle(
83 scoped_refptr
<DownloadRequestLimiter
> limiter
,
84 int render_process_id
,
87 const std::string
& request_method
)
88 : querying_limiter_(true),
89 request_allowed_(false),
90 request_deferred_(false) {
91 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
92 BrowserThread::PostTask(
93 BrowserThread::UI
, FROM_HERE
,
95 &CanDownloadOnUIThread
,
96 base::Passed(scoped_ptr
<DownloadRequestInfo
>(new DownloadRequestInfo(
97 limiter
, render_process_id
, render_view_id
, url
, request_method
,
98 base::Bind(&OnCanDownloadDecided
, AsWeakPtr()))))));
101 DownloadResourceThrottle::~DownloadResourceThrottle() {
104 void DownloadResourceThrottle::WillStartRequest(bool* defer
) {
108 void DownloadResourceThrottle::WillRedirectRequest(
109 const net::RedirectInfo
& redirect_info
,
114 void DownloadResourceThrottle::WillProcessResponse(bool* defer
) {
118 const char* DownloadResourceThrottle::GetNameForLogging() const {
119 return "DownloadResourceThrottle";
122 void DownloadResourceThrottle::WillDownload(bool* defer
) {
123 DCHECK(!request_deferred_
);
125 // Defer the download until we have the DownloadRequestLimiter result.
126 if (querying_limiter_
) {
127 request_deferred_
= true;
132 if (!request_allowed_
)
133 controller()->Cancel();
136 void DownloadResourceThrottle::ContinueDownload(bool allow
) {
137 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
138 querying_limiter_
= false;
139 request_allowed_
= allow
;
142 // Presumes all downloads initiated by navigation use this throttle and
143 // nothing else does.
144 RecordDownloadSource(DOWNLOAD_INITIATED_BY_NAVIGATION
);
146 RecordDownloadCount(CHROME_DOWNLOAD_COUNT_BLOCKED_BY_THROTTLING
);
149 if (request_deferred_
) {
150 request_deferred_
= false;
152 controller()->Resume();
154 controller()->Cancel();