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 content::DownloadControllerAndroid::Get()->AcquireFileAccessPermission(
55 info
->render_process_id
, info
->render_view_id
,
56 base::Bind(&OnAcquireFileAccessPermissionDone
,
57 base::Passed(info
.Pass())));
59 CanDownload(info
.Pass());
65 DownloadResourceThrottle::DownloadRequestInfo::DownloadRequestInfo(
66 scoped_refptr
<DownloadRequestLimiter
> limiter
,
67 int render_process_id
,
70 const std::string
& request_method
,
71 const DownloadRequestLimiter::Callback
& continue_callback
)
73 render_process_id(render_process_id
),
74 render_view_id(render_view_id
),
76 request_method(request_method
),
77 continue_callback(continue_callback
) {}
79 DownloadResourceThrottle::DownloadRequestInfo::~DownloadRequestInfo() {}
81 DownloadResourceThrottle::DownloadResourceThrottle(
82 scoped_refptr
<DownloadRequestLimiter
> limiter
,
83 int render_process_id
,
86 const std::string
& request_method
)
87 : querying_limiter_(true),
88 request_allowed_(false),
89 request_deferred_(false) {
90 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
91 BrowserThread::PostTask(
92 BrowserThread::UI
, FROM_HERE
,
94 &CanDownloadOnUIThread
,
95 base::Passed(scoped_ptr
<DownloadRequestInfo
>(new DownloadRequestInfo(
96 limiter
, render_process_id
, render_view_id
, url
, request_method
,
97 base::Bind(&OnCanDownloadDecided
, AsWeakPtr()))))));
100 DownloadResourceThrottle::~DownloadResourceThrottle() {
103 void DownloadResourceThrottle::WillStartRequest(bool* defer
) {
107 void DownloadResourceThrottle::WillRedirectRequest(
108 const net::RedirectInfo
& redirect_info
,
113 void DownloadResourceThrottle::WillProcessResponse(bool* defer
) {
117 const char* DownloadResourceThrottle::GetNameForLogging() const {
118 return "DownloadResourceThrottle";
121 void DownloadResourceThrottle::WillDownload(bool* defer
) {
122 DCHECK(!request_deferred_
);
124 // Defer the download until we have the DownloadRequestLimiter result.
125 if (querying_limiter_
) {
126 request_deferred_
= true;
131 if (!request_allowed_
)
132 controller()->Cancel();
135 void DownloadResourceThrottle::ContinueDownload(bool allow
) {
136 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
137 querying_limiter_
= false;
138 request_allowed_
= allow
;
141 // Presumes all downloads initiated by navigation use this throttle and
142 // nothing else does.
143 RecordDownloadSource(DOWNLOAD_INITIATED_BY_NAVIGATION
);
145 RecordDownloadCount(CHROME_DOWNLOAD_COUNT_BLOCKED_BY_THROTTLING
);
148 if (request_deferred_
) {
149 request_deferred_
= false;
151 controller()->Resume();
153 controller()->Cancel();