Index: android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.cc |
diff --git a/android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.cc b/android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.cc |
index b24eb2b56eac50e61bccdadb308a07a74515d6c0..f1e756f2318f6b3b5d0052d3c4a37feb17d4e95a 100644 |
--- a/android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.cc |
+++ b/android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.cc |
@@ -10,6 +10,7 @@ |
#include "base/memory/scoped_ptr.h" |
#include "base/memory/scoped_vector.h" |
#include "content/components/navigation_interception/intercept_navigation_delegate.h" |
+#include "content/public/browser/browser_thread.h" |
#include "content/public/browser/resource_controller.h" |
#include "content/public/browser/resource_dispatcher_host.h" |
#include "content/public/browser/resource_dispatcher_host_login_delegate.h" |
@@ -23,6 +24,7 @@ using content::InterceptNavigationDelegate; |
namespace { |
using android_webview::AwContentsIoThreadClient; |
+using content::BrowserThread; |
base::LazyInstance<android_webview::AwResourceDispatcherHostDelegate> |
g_webview_resource_dispatcher_host_delegate = LAZY_INSTANCE_INITIALIZER; |
@@ -59,17 +61,7 @@ class MaybeCancelResourceThrottle : public content::ResourceThrottle { |
}; |
void MaybeCancelResourceThrottle::WillStartRequest(bool* defer) { |
- // If there is no IO thread client set at this point, use a |
- // restrictive policy. This can happen for blocked popup |
- // windows for example. |
- // TODO(benm): Revert this to a DCHECK when the we support |
- // pop up windows being created in the WebView, as at that |
- // time we should always have an IoThreadClient at this |
- // point (i.e., the one associated with the new popup). |
- if (!GetIoThreadClient()) { |
- controller()->CancelWithError(net::ERR_ACCESS_DENIED); |
- return; |
- } |
+ DCHECK(GetIoThreadClient()); |
// Part of implementation of WebSettings.allowContentAccess. |
if (request_->url().SchemeIs(android_webview::kContentScheme) && |
@@ -100,6 +92,53 @@ void MaybeCancelResourceThrottle::WillStartRequest(bool* defer) { |
} |
} |
+class DeferUntilIoThreadClientReadyThrottle |
+ : public content::ResourceThrottle, |
+ public AwContentsIoThreadClient::ReadyObserver { |
+ public: |
+ DeferUntilIoThreadClientReadyThrottle(int child_id, int route_id) |
+ : child_id_(child_id), |
+ route_id_(route_id), |
+ resumed_(false) { |
+ } |
+ |
+ virtual ~DeferUntilIoThreadClientReadyThrottle() { |
+ AwContentsIoThreadClient::RemoveReadyObserver(this); |
+ } |
+ |
+ virtual void WillStartRequest(bool* defer) OVERRIDE { |
+ MaybeDeferRequest(defer); |
+ } |
+ |
+ virtual void WillRedirectRequest(const GURL& new_url, bool* defer) OVERRIDE { |
+ MaybeDeferRequest(defer); |
+ } |
+ |
+ void MaybeDeferRequest(bool* defer) { |
+ if (!AwContentsIoThreadClient::FromID(child_id_, route_id_)) { |
+ *defer = true; |
+ AwContentsIoThreadClient::AddReadyObserver(this); |
+ } else { |
+ *defer = false; |
+ } |
+ } |
+ |
+ void OnIoThreadClientReady(int new_child_id, int new_route_id) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
+ // If we've now got the IoThreadClient that we were waiting on, |
+ // resume the request. |
+ if (!resumed_ && new_child_id == child_id_ && new_route_id == route_id_) { |
mkosiba (inactive)
2012/11/16 12:28:32
it seems like this is a good place to run all of t
benm (inactive)
2012/11/16 12:36:31
IoThreadClientThrottle maybe?
With a class commen
|
+ controller()->Resume(); |
+ resumed_ = true; |
+ } |
+ } |
+ |
+private: |
+ int child_id_; |
+ int route_id_; |
+ bool resumed_; |
+}; |
+ |
} // namespace |
namespace android_webview { |
@@ -127,6 +166,12 @@ void AwResourceDispatcherHostDelegate::RequestBeginning( |
bool is_continuation_of_transferred_request, |
ScopedVector<content::ResourceThrottle>* throttles) { |
+ // If there's no IoClient yet, then we need to defer until there is one. |
+ if (!AwContentsIoThreadClient::FromID(child_id, route_id)) { |
+ throttles->push_back(new DeferUntilIoThreadClientReadyThrottle( |
+ child_id, route_id)); |
+ } |
+ |
throttles->push_back(new MaybeCancelResourceThrottle( |
child_id, route_id, request)); |