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

Unified 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: Address Marcin's comments. Created 8 years, 1 month 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 side-by-side diff with in-line comments
Download patch
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..198b7920420a0a3fa640bc8c97278b0ae0453d51 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;
@@ -37,68 +39,114 @@ void SetOnlyAllowLoadFromCache(
request->set_load_flags(load_flags);
}
-// May cancel this resource request based on result of Java callbacks.
-class MaybeCancelResourceThrottle : public content::ResourceThrottle {
+// Calls through the IoThreadClient to check the embedders settings to determine
+// if the request should be cancelled. There may not always be an IoThreadClient
+// available for the |child_id|, |route_id| pair (in the case of newly created
+// pop up windows, for example) and in that case the request and the client
+// callbacks will be deferred the request until a client is ready.
+class IoThreadClientThrottle
+ : public content::ResourceThrottle,
+ public AwContentsIoThreadClient::ReadyObserver {
public:
- MaybeCancelResourceThrottle(int child_id,
- int route_id,
- net::URLRequest* request)
- : child_id_(child_id),
- route_id_(route_id),
- request_(request) { }
- virtual void WillStartRequest(bool* defer) OVERRIDE;
-
- scoped_ptr<AwContentsIoThreadClient> GetIoThreadClient() {
- return AwContentsIoThreadClient::FromID(child_id_, route_id_);
+ IoThreadClientThrottle(int child_id, int route_id, net::URLRequest* request)
+ : child_id_(child_id),
+ route_id_(route_id),
+ request_(request),
+ handled_(false),
+ added_observer_(false) {
}
- private:
- int child_id_;
- int route_id_;
- net::URLRequest* request_;
-};
+ virtual ~IoThreadClientThrottle() {
+ if (added_observer_) {
+ AwContentsIoThreadClient::RemoveReadyObserver(this);
+ }
+ }
-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;
+ virtual void WillStartRequest(bool* defer) OVERRIDE {
+ if (!MaybeDeferRequest(defer)) {
+ MaybeBlockRequest();
+ }
}
- // Part of implementation of WebSettings.allowContentAccess.
- if (request_->url().SchemeIs(android_webview::kContentScheme) &&
- GetIoThreadClient()->ShouldBlockContentUrls()) {
- controller()->CancelWithError(net::ERR_ACCESS_DENIED);
- return;
+ virtual void WillRedirectRequest(const GURL& new_url, bool* defer) OVERRIDE {
+ WillStartRequest(defer);
}
- // Part of implementation of WebSettings.allowFileAccess.
- if (request_->url().SchemeIsFile() &&
- GetIoThreadClient()->ShouldBlockFileUrls()) {
- const GURL& url = request_->url();
- if (!url.has_path() ||
- // Application's assets and resources are always available.
- (url.path().find(android_webview::kAndroidResourcePath) != 0 &&
- url.path().find(android_webview::kAndroidAssetPath) != 0)) {
- controller()->CancelWithError(net::ERR_ACCESS_DENIED);
- return;
+ bool MaybeDeferRequest(bool* defer) {
+ scoped_ptr<AwContentsIoThreadClient> io_client =
+ AwContentsIoThreadClient::FromID(child_id_, route_id_);
+ if (!io_client.get()) {
+ *defer = true;
+ AwContentsIoThreadClient::AddReadyObserver(this);
+ added_observer_ = true;
+ return true;
+ } else {
+ *defer = false;
+ }
+ return 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 (!handled_ && new_child_id == child_id_ && new_route_id == route_id_) {
+ if (!MaybeBlockRequest()) {
+ controller()->Resume();
+ handled_ = true;
+ }
}
joth 2012/11/16 21:52:57 add: AwContentsIoThreadClient::RemoveReadyObserve
benm (inactive) 2012/11/28 20:00:05 This should all go away and become simpler in next
}
- if (GetIoThreadClient()->ShouldBlockNetworkLoads()) {
- if (request_->url().SchemeIs(chrome::kFtpScheme)) {
+ bool MaybeBlockRequest() {
+ if (ShouldBlockRequest()) {
controller()->CancelWithError(net::ERR_ACCESS_DENIED);
- return;
+ handled_ = true;
+ return true;
}
- SetOnlyAllowLoadFromCache(request_);
+ return false;
}
-}
+
+ bool ShouldBlockRequest() {
+ scoped_ptr<AwContentsIoThreadClient> io_client =
+ AwContentsIoThreadClient::FromID(child_id_, route_id_);
+ DCHECK(io_client.get());
+
+ // Part of implementation of WebSettings.allowContentAccess.
+ if (request_->url().SchemeIs(android_webview::kContentScheme) &&
+ io_client->ShouldBlockContentUrls()) {
+ return true;
+ }
+
+ // Part of implementation of WebSettings.allowFileAccess.
+ if (request_->url().SchemeIsFile() &&
+ io_client->ShouldBlockFileUrls()) {
+ const GURL& url = request_->url();
+ if (!url.has_path() ||
+ // Application's assets and resources are always available.
+ (url.path().find(android_webview::kAndroidResourcePath) != 0 &&
+ url.path().find(android_webview::kAndroidAssetPath) != 0)) {
+ return true;
+ }
+ }
+
+ if (io_client->ShouldBlockNetworkLoads()) {
+ if (request_->url().SchemeIs(chrome::kFtpScheme)) {
+ return true;
+ }
+ SetOnlyAllowLoadFromCache(request_);
+ }
+
+ return false;
+ }
+
+private:
+ int child_id_;
+ int route_id_;
+ net::URLRequest* request_;
+ bool handled_;
+ bool added_observer_;
+};
} // namespace
@@ -127,8 +175,7 @@ void AwResourceDispatcherHostDelegate::RequestBeginning(
bool is_continuation_of_transferred_request,
ScopedVector<content::ResourceThrottle>* throttles) {
- throttles->push_back(new MaybeCancelResourceThrottle(
- child_id, route_id, request));
+ throttles->push_back(new IoThreadClientThrottle(child_id, route_id, request));
if (resource_type == ResourceType::MAIN_FRAME) {
throttles->push_back(InterceptNavigationDelegate::CreateThrottleFor(

Powered by Google App Engine
This is Rietveld 408576698