Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(497)

Side by Side Diff: android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.cc

Issue 11348075: [Android WebView] AwContentsClient.shouldCreate window callback part 2. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix spurious includes. Created 8 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 "android_webview/browser/renderer_host/aw_resource_dispatcher_host_dele gate.h" 5 #include "android_webview/browser/renderer_host/aw_resource_dispatcher_host_dele gate.h"
6 6
7 #include "android_webview/browser/aw_contents_io_thread_client.h"
7 #include "android_webview/browser/aw_login_delegate.h" 8 #include "android_webview/browser/aw_login_delegate.h"
8 #include "android_webview/browser/aw_contents_io_thread_client.h"
9 #include "android_webview/common/url_constants.h" 9 #include "android_webview/common/url_constants.h"
10 #include "base/memory/scoped_ptr.h" 10 #include "base/memory/scoped_ptr.h"
11 #include "base/memory/scoped_vector.h" 11 #include "base/memory/scoped_vector.h"
12 #include "content/components/navigation_interception/intercept_navigation_delega te.h" 12 #include "content/components/navigation_interception/intercept_navigation_delega te.h"
13 #include "content/public/browser/browser_thread.h"
13 #include "content/public/browser/resource_controller.h" 14 #include "content/public/browser/resource_controller.h"
14 #include "content/public/browser/resource_dispatcher_host.h" 15 #include "content/public/browser/resource_dispatcher_host.h"
15 #include "content/public/browser/resource_dispatcher_host_login_delegate.h" 16 #include "content/public/browser/resource_dispatcher_host_login_delegate.h"
16 #include "content/public/browser/resource_throttle.h" 17 #include "content/public/browser/resource_throttle.h"
17 #include "content/public/common/url_constants.h" 18 #include "content/public/common/url_constants.h"
18 #include "net/base/load_flags.h" 19 #include "net/base/load_flags.h"
19 #include "net/url_request/url_request.h" 20 #include "net/url_request/url_request.h"
20 21
22 using android_webview::AwContentsIoThreadClient;
23 using content::BrowserThread;
21 using content::InterceptNavigationDelegate; 24 using content::InterceptNavigationDelegate;
22 25
23 namespace { 26 namespace {
24 27
25 using android_webview::AwContentsIoThreadClient;
26
27 base::LazyInstance<android_webview::AwResourceDispatcherHostDelegate> 28 base::LazyInstance<android_webview::AwResourceDispatcherHostDelegate>
28 g_webview_resource_dispatcher_host_delegate = LAZY_INSTANCE_INITIALIZER; 29 g_webview_resource_dispatcher_host_delegate = LAZY_INSTANCE_INITIALIZER;
29 30
30 void SetCacheControlFlag( 31 void SetCacheControlFlag(
31 net::URLRequest* request, int flag) { 32 net::URLRequest* request, int flag) {
32 const int all_cache_control_flags = net::LOAD_BYPASS_CACHE | 33 const int all_cache_control_flags = net::LOAD_BYPASS_CACHE |
33 net::LOAD_VALIDATE_CACHE | 34 net::LOAD_VALIDATE_CACHE |
34 net::LOAD_PREFERRING_CACHE | 35 net::LOAD_PREFERRING_CACHE |
35 net::LOAD_ONLY_FROM_CACHE; 36 net::LOAD_ONLY_FROM_CACHE;
36 DCHECK((flag & all_cache_control_flags) == flag); 37 DCHECK((flag & all_cache_control_flags) == flag);
37 int load_flags = request->load_flags(); 38 int load_flags = request->load_flags();
38 load_flags &= ~all_cache_control_flags; 39 load_flags &= ~all_cache_control_flags;
39 load_flags |= flag; 40 load_flags |= flag;
40 request->set_load_flags(load_flags); 41 request->set_load_flags(load_flags);
41 } 42 }
42 43
44 } // namespace
45
46 namespace android_webview {
47
43 // Calls through the IoThreadClient to check the embedders settings to determine 48 // Calls through the IoThreadClient to check the embedders settings to determine
44 // if the request should be cancelled. 49 // if the request should be cancelled. There may not always be an IoThreadClient
50 // available for the |child_id|, |route_id| pair (in the case of newly created
51 // pop up windows, for example) and in that case the request and the client
52 // callbacks will be deferred the request until a client is ready.
45 class IoThreadClientThrottle : public content::ResourceThrottle { 53 class IoThreadClientThrottle : public content::ResourceThrottle {
46 public: 54 public:
47 IoThreadClientThrottle(int child_id, 55 IoThreadClientThrottle(int child_id,
48 int route_id, 56 int route_id,
49 net::URLRequest* request) 57 net::URLRequest* request);
50 : child_id_(child_id), 58 virtual ~IoThreadClientThrottle();
51 route_id_(route_id), 59
52 request_(request) { } 60 // From content::ResourceThrottle
53 virtual void WillStartRequest(bool* defer) OVERRIDE; 61 virtual void WillStartRequest(bool* defer) OVERRIDE;
62 virtual void WillRedirectRequest(const GURL& new_url, bool* defer) OVERRIDE;
54 63
55 scoped_ptr<AwContentsIoThreadClient> GetIoThreadClient() { 64 bool MaybeDeferRequest(bool* defer);
56 return AwContentsIoThreadClient::FromID(child_id_, route_id_); 65 void OnIoThreadClientReady(int new_child_id, int new_route_id);
57 } 66 bool MaybeBlockRequest();
67 bool ShouldBlockRequest();
68 scoped_ptr<AwContentsIoThreadClient> GetIoThreadClient();
69 int get_child_id() const { return child_id_; }
70 int get_route_id() const { return route_id_; }
58 71
59 private: 72 private:
60 int child_id_; 73 int child_id_;
61 int route_id_; 74 int route_id_;
62 net::URLRequest* request_; 75 net::URLRequest* request_;
63 }; 76 };
64 77
78 IoThreadClientThrottle::IoThreadClientThrottle(int child_id,
79 int route_id,
80 net::URLRequest* request)
81 : child_id_(child_id),
82 route_id_(route_id),
83 request_(request) { }
84
85 IoThreadClientThrottle::~IoThreadClientThrottle() {
86 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
87 g_webview_resource_dispatcher_host_delegate.Get().
88 RemovePendingThrottleOnIoThread(this);
89 }
90
65 void IoThreadClientThrottle::WillStartRequest(bool* defer) { 91 void IoThreadClientThrottle::WillStartRequest(bool* defer) {
66 // If there is no IO thread client set at this point, use a 92 if (!MaybeDeferRequest(defer)) {
67 // restrictive policy. This can happen for blocked popup 93 MaybeBlockRequest();
68 // windows for example. 94 }
69 // TODO(benm): Revert this to a DCHECK when the we support 95 }
70 // pop up windows being created in the WebView, as at that 96
71 // time we should always have an IoThreadClient at this 97 void IoThreadClientThrottle::WillRedirectRequest(const GURL& new_url,
72 // point (i.e., the one associated with the new popup). 98 bool* defer) {
73 if (!GetIoThreadClient()) { 99 WillStartRequest(defer);
100 }
101
102 bool IoThreadClientThrottle::MaybeDeferRequest(bool* defer) {
103 scoped_ptr<AwContentsIoThreadClient> io_client =
104 AwContentsIoThreadClient::FromID(child_id_, route_id_);
105 *defer = false;
106 if (!io_client.get()) {
107 *defer = true;
108 AwResourceDispatcherHostDelegate::AddPendingThrottle(
109 child_id_, route_id_, this);
110 }
111 return *defer;
112 }
113
114 void IoThreadClientThrottle::OnIoThreadClientReady(int new_child_id,
115 int new_route_id) {
116 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
117
118 if (!MaybeBlockRequest()) {
119 controller()->Resume();
120 }
121 }
122
123 bool IoThreadClientThrottle::MaybeBlockRequest() {
124 if (ShouldBlockRequest()) {
74 controller()->CancelWithError(net::ERR_ACCESS_DENIED); 125 controller()->CancelWithError(net::ERR_ACCESS_DENIED);
75 return; 126 return true;
76 } 127 }
128 return false;
129 }
130
131 bool IoThreadClientThrottle::ShouldBlockRequest() {
132 scoped_ptr<AwContentsIoThreadClient> io_client =
133 AwContentsIoThreadClient::FromID(child_id_, route_id_);
134 DCHECK(io_client.get());
77 135
78 // Part of implementation of WebSettings.allowContentAccess. 136 // Part of implementation of WebSettings.allowContentAccess.
79 if (request_->url().SchemeIs(android_webview::kContentScheme) && 137 if (request_->url().SchemeIs(android_webview::kContentScheme) &&
80 GetIoThreadClient()->ShouldBlockContentUrls()) { 138 io_client->ShouldBlockContentUrls()) {
81 controller()->CancelWithError(net::ERR_ACCESS_DENIED); 139 return true;
82 return;
83 } 140 }
84 141
85 // Part of implementation of WebSettings.allowFileAccess. 142 // Part of implementation of WebSettings.allowFileAccess.
86 if (request_->url().SchemeIsFile() && 143 if (request_->url().SchemeIsFile() &&
87 GetIoThreadClient()->ShouldBlockFileUrls()) { 144 io_client->ShouldBlockFileUrls()) {
88 const GURL& url = request_->url(); 145 const GURL& url = request_->url();
89 if (!url.has_path() || 146 if (!url.has_path() ||
90 // Application's assets and resources are always available. 147 // Application's assets and resources are always available.
91 (url.path().find(android_webview::kAndroidResourcePath) != 0 && 148 (url.path().find(android_webview::kAndroidResourcePath) != 0 &&
92 url.path().find(android_webview::kAndroidAssetPath) != 0)) { 149 url.path().find(android_webview::kAndroidAssetPath) != 0)) {
93 controller()->CancelWithError(net::ERR_ACCESS_DENIED); 150 return true;
94 return;
95 } 151 }
96 } 152 }
97 153
98 if (GetIoThreadClient()->ShouldBlockNetworkLoads()) { 154 if (io_client->ShouldBlockNetworkLoads()) {
99 if (request_->url().SchemeIs(chrome::kFtpScheme)) { 155 if (request_->url().SchemeIs(chrome::kFtpScheme)) {
100 controller()->CancelWithError(net::ERR_ACCESS_DENIED); 156 return true;
101 return;
102 } 157 }
103 SetCacheControlFlag(request_, net::LOAD_ONLY_FROM_CACHE); 158 SetCacheControlFlag(request_, net::LOAD_ONLY_FROM_CACHE);
104 } else { 159 } else {
105 AwContentsIoThreadClient::CacheMode cache_mode = 160 AwContentsIoThreadClient::CacheMode cache_mode =
106 GetIoThreadClient()->GetCacheMode(); 161 GetIoThreadClient()->GetCacheMode();
107 switch(cache_mode) { 162 switch(cache_mode) {
108 case AwContentsIoThreadClient::LOAD_CACHE_ELSE_NETWORK: 163 case AwContentsIoThreadClient::LOAD_CACHE_ELSE_NETWORK:
109 SetCacheControlFlag(request_, net::LOAD_PREFERRING_CACHE); 164 SetCacheControlFlag(request_, net::LOAD_PREFERRING_CACHE);
110 break; 165 break;
111 case AwContentsIoThreadClient::LOAD_NO_CACHE: 166 case AwContentsIoThreadClient::LOAD_NO_CACHE:
112 SetCacheControlFlag(request_, net::LOAD_BYPASS_CACHE); 167 SetCacheControlFlag(request_, net::LOAD_BYPASS_CACHE);
113 break; 168 break;
114 case AwContentsIoThreadClient::LOAD_CACHE_ONLY: 169 case AwContentsIoThreadClient::LOAD_CACHE_ONLY:
115 SetCacheControlFlag(request_, net::LOAD_ONLY_FROM_CACHE); 170 SetCacheControlFlag(request_, net::LOAD_ONLY_FROM_CACHE);
116 break; 171 break;
117 default: 172 default:
118 break; 173 break;
119 } 174 }
120 } 175 }
176 return false;
121 } 177 }
122 178
123 } // namespace 179 scoped_ptr<AwContentsIoThreadClient>
124 180 IoThreadClientThrottle::GetIoThreadClient() {
125 namespace android_webview { 181 return AwContentsIoThreadClient::FromID(child_id_, route_id_);
182 }
126 183
127 // static 184 // static
128 void AwResourceDispatcherHostDelegate::ResourceDispatcherHostCreated() { 185 void AwResourceDispatcherHostDelegate::ResourceDispatcherHostCreated() {
129 content::ResourceDispatcherHost::Get()->SetDelegate( 186 content::ResourceDispatcherHost::Get()->SetDelegate(
130 &g_webview_resource_dispatcher_host_delegate.Get()); 187 &g_webview_resource_dispatcher_host_delegate.Get());
131 } 188 }
132 189
133 AwResourceDispatcherHostDelegate::AwResourceDispatcherHostDelegate() 190 AwResourceDispatcherHostDelegate::AwResourceDispatcherHostDelegate()
134 : content::ResourceDispatcherHostDelegate() { 191 : content::ResourceDispatcherHostDelegate() {
135 } 192 }
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
186 243
187 bool AwResourceDispatcherHostDelegate::HandleExternalProtocol(const GURL& url, 244 bool AwResourceDispatcherHostDelegate::HandleExternalProtocol(const GURL& url,
188 int child_id, 245 int child_id,
189 int route_id) { 246 int route_id) {
190 // The AwURLRequestJobFactory implementation should ensure this method never 247 // The AwURLRequestJobFactory implementation should ensure this method never
191 // gets called. 248 // gets called.
192 NOTREACHED(); 249 NOTREACHED();
193 return false; 250 return false;
194 } 251 }
195 252
253 void AwResourceDispatcherHostDelegate::RemovePendingThrottleOnIoThread(
254 IoThreadClientThrottle* throttle) {
255 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
256 PendingThrottleMap::iterator it = pending_throttles_.find(
257 ChildRouteIDPair(throttle->get_child_id(), throttle->get_route_id()));
258 if (it != pending_throttles_.end()) {
259 pending_throttles_.erase(it);
260 }
196 } 261 }
262
263 // static
264 void AwResourceDispatcherHostDelegate::OnIoThreadClientReady(
265 int new_child_id,
266 int new_route_id) {
267 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
268 base::Bind(
269 &AwResourceDispatcherHostDelegate::OnIoThreadClientReadyInternal,
270 base::Unretained(
271 g_webview_resource_dispatcher_host_delegate.Pointer()),
272 new_child_id, new_route_id));
273 }
274
275 // static
276 void AwResourceDispatcherHostDelegate::AddPendingThrottle(
277 int child_id,
278 int route_id,
279 IoThreadClientThrottle* pending_throttle) {
280 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
281 base::Bind(
282 &AwResourceDispatcherHostDelegate::AddPendingThrottleOnIoThread,
283 base::Unretained(
284 g_webview_resource_dispatcher_host_delegate.Pointer()),
285 child_id, route_id, pending_throttle));
286 }
287
288 void AwResourceDispatcherHostDelegate::AddPendingThrottleOnIoThread(
289 int child_id,
290 int route_id,
291 IoThreadClientThrottle* pending_throttle) {
292 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
293 pending_throttles_.insert(
294 std::pair<ChildRouteIDPair, IoThreadClientThrottle*>(
295 ChildRouteIDPair(child_id, route_id), pending_throttle));
296 }
297
298 void AwResourceDispatcherHostDelegate::OnIoThreadClientReadyInternal(
299 int new_child_id,
300 int new_route_id) {
301 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
302 PendingThrottleMap::iterator it = pending_throttles_.find(
303 ChildRouteIDPair(new_child_id, new_route_id));
304
305 if (it != pending_throttles_.end()) {
306 IoThreadClientThrottle* throttle = it->second;
307 throttle->OnIoThreadClientReady(new_child_id, new_route_id);
308 pending_throttles_.erase(it);
309 }
310 }
311
312 } // namespace android_webview
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698