Commit ea1c1679 authored by sgurun's avatar sgurun Committed by Commit bot

Introduce a secondary map

Once browser initiated nagivations are enabled, we need a secondary map to map framenodeid's to IO thread clients.

BUG=645983

Review-Url: https://codereview.chromium.org/2737663004
Cr-Commit-Position: refs/heads/master@{#456126}
parent 1bbc9fc2
...@@ -63,6 +63,11 @@ class AwContentsIoThreadClient { ...@@ -63,6 +63,11 @@ class AwContentsIoThreadClient {
static std::unique_ptr<AwContentsIoThreadClient> FromID(int render_process_id, static std::unique_ptr<AwContentsIoThreadClient> FromID(int render_process_id,
int render_frame_id); int render_frame_id);
// This map is useful when browser side navigations are enabled as
// render_frame_ids will not be valid anymore for some of the navigations.
static std::unique_ptr<AwContentsIoThreadClient> FromID(
int frame_tree_node_id);
// Returns the global thread client for service worker related callbacks. // Returns the global thread client for service worker related callbacks.
// An empty scoped_ptr is a valid return value. // An empty scoped_ptr is a valid return value.
static std::unique_ptr<AwContentsIoThreadClient> static std::unique_ptr<AwContentsIoThreadClient>
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include "content/public/browser/resource_request_info.h" #include "content/public/browser/resource_request_info.h"
#include "net/http/http_response_headers.h" #include "net/http/http_response_headers.h"
#include "net/url_request/url_request_job.h" #include "net/url_request/url_request_job.h"
#include "url/url_constants.h"
namespace android_webview { namespace android_webview {
...@@ -119,13 +120,22 @@ std::unique_ptr<AwContentsIoThreadClient> GetCorrespondingIoThreadClient( ...@@ -119,13 +120,22 @@ std::unique_ptr<AwContentsIoThreadClient> GetCorrespondingIoThreadClient(
net::URLRequest* request) { net::URLRequest* request) {
if (content::ResourceRequestInfo::OriginatedFromServiceWorker(request)) if (content::ResourceRequestInfo::OriginatedFromServiceWorker(request))
return AwContentsIoThreadClient::GetServiceWorkerIoThreadClient(); return AwContentsIoThreadClient::GetServiceWorkerIoThreadClient();
int render_process_id, render_frame_id; int render_process_id, render_frame_id;
if (!content::ResourceRequestInfo::GetRenderFrameForRequest( if (!content::ResourceRequestInfo::GetRenderFrameForRequest(
request, &render_process_id, &render_frame_id)) { request, &render_process_id, &render_frame_id)) {
return nullptr; return nullptr;
} }
if (render_process_id == -1 || render_frame_id == -1) {
const content::ResourceRequestInfo* resourceRequestInfo =
content::ResourceRequestInfo::ForRequest(request);
if (resourceRequestInfo == nullptr) {
return nullptr;
}
return AwContentsIoThreadClient::FromID(
resourceRequestInfo->GetFrameTreeNodeId());
}
return AwContentsIoThreadClient::FromID(render_process_id, render_frame_id); return AwContentsIoThreadClient::FromID(render_process_id, render_frame_id);
} }
...@@ -144,6 +154,13 @@ net::URLRequestJob* AwRequestInterceptor::MaybeInterceptRequest( ...@@ -144,6 +154,13 @@ net::URLRequestJob* AwRequestInterceptor::MaybeInterceptRequest(
if (request->GetUserData(kRequestAlreadyHasJobDataKey)) if (request->GetUserData(kRequestAlreadyHasJobDataKey))
return nullptr; return nullptr;
// With PlzNavigate, we now seem to receive blob URLs in interceptor.
// Ignore these URLs.
// TODO(sgurun) is this the best place to do that? Talk with jam@.
if (request->url().SchemeIs(url::kBlobScheme)) {
return nullptr;
}
std::unique_ptr<AwContentsIoThreadClient> io_thread_client = std::unique_ptr<AwContentsIoThreadClient> io_thread_client =
GetCorrespondingIoThreadClient(request); GetCorrespondingIoThreadClient(request);
......
...@@ -162,6 +162,16 @@ IoThreadClientThrottle::GetIoThreadClient() const { ...@@ -162,6 +162,16 @@ IoThreadClientThrottle::GetIoThreadClient() const {
if (content::ResourceRequestInfo::OriginatedFromServiceWorker(request_)) if (content::ResourceRequestInfo::OriginatedFromServiceWorker(request_))
return AwContentsIoThreadClient::GetServiceWorkerIoThreadClient(); return AwContentsIoThreadClient::GetServiceWorkerIoThreadClient();
if (render_process_id_ == -1 || render_frame_id_ == -1) {
const content::ResourceRequestInfo* resourceRequestInfo =
content::ResourceRequestInfo::ForRequest(request_);
if (resourceRequestInfo == nullptr) {
return nullptr;
}
return AwContentsIoThreadClient::FromID(
resourceRequestInfo->GetFrameTreeNodeId());
}
return AwContentsIoThreadClient::FromID(render_process_id_, render_frame_id_); return AwContentsIoThreadClient::FromID(render_process_id_, render_frame_id_);
} }
......
...@@ -57,6 +57,11 @@ IoThreadClientData::IoThreadClientData() : pending_association(false) {} ...@@ -57,6 +57,11 @@ IoThreadClientData::IoThreadClientData() : pending_association(false) {}
typedef map<pair<int, int>, IoThreadClientData> typedef map<pair<int, int>, IoThreadClientData>
RenderFrameHostToIoThreadClientType; RenderFrameHostToIoThreadClientType;
// When browser side navigation is enabled, RenderFrameIDs do not have
// valid render process host and render frame ids for frame navigations.
// We need to identify these by using Frame Tree Node ids.
typedef map<int, IoThreadClientData> FrameTreeNodeToIoThreadClientType;
static pair<int, int> GetRenderFrameHostIdPair(RenderFrameHost* rfh) { static pair<int, int> GetRenderFrameHostIdPair(RenderFrameHost* rfh) {
return pair<int, int>(rfh->GetProcess()->GetID(), rfh->GetRoutingID()); return pair<int, int>(rfh->GetProcess()->GetID(), rfh->GetRoutingID());
} }
...@@ -69,9 +74,14 @@ class RfhToIoThreadClientMap { ...@@ -69,9 +74,14 @@ class RfhToIoThreadClientMap {
bool Get(pair<int, int> rfh_id, IoThreadClientData* client); bool Get(pair<int, int> rfh_id, IoThreadClientData* client);
void Erase(pair<int, int> rfh_id); void Erase(pair<int, int> rfh_id);
void Set(int frame_tree_node_id, const IoThreadClientData& client);
bool Get(int frame_tree_node_id, IoThreadClientData* client);
void Erase(int frame_tree_node_id);
private: private:
base::Lock map_lock_; base::Lock map_lock_;
RenderFrameHostToIoThreadClientType rfh_to_io_thread_client_; RenderFrameHostToIoThreadClientType rfh_to_io_thread_client_;
FrameTreeNodeToIoThreadClientType frame_tree_node_to_io_thread_client_;
}; };
// static // static
...@@ -110,6 +120,29 @@ void RfhToIoThreadClientMap::Erase(pair<int, int> rfh_id) { ...@@ -110,6 +120,29 @@ void RfhToIoThreadClientMap::Erase(pair<int, int> rfh_id) {
rfh_to_io_thread_client_.erase(rfh_id); rfh_to_io_thread_client_.erase(rfh_id);
} }
void RfhToIoThreadClientMap::Set(int frame_tree_node_id,
const IoThreadClientData& client) {
base::AutoLock lock(map_lock_);
frame_tree_node_to_io_thread_client_[frame_tree_node_id] = client;
}
bool RfhToIoThreadClientMap::Get(int frame_tree_node_id,
IoThreadClientData* client) {
base::AutoLock lock(map_lock_);
FrameTreeNodeToIoThreadClientType::iterator iterator =
frame_tree_node_to_io_thread_client_.find(frame_tree_node_id);
if (iterator == frame_tree_node_to_io_thread_client_.end())
return false;
*client = iterator->second;
return true;
}
void RfhToIoThreadClientMap::Erase(int frame_tree_node_id) {
base::AutoLock lock(map_lock_);
frame_tree_node_to_io_thread_client_.erase(frame_tree_node_id);
}
// ClientMapEntryUpdater ------------------------------------------------------ // ClientMapEntryUpdater ------------------------------------------------------
class ClientMapEntryUpdater : public content::WebContentsObserver { class ClientMapEntryUpdater : public content::WebContentsObserver {
...@@ -141,12 +174,15 @@ void ClientMapEntryUpdater::RenderFrameCreated(RenderFrameHost* rfh) { ...@@ -141,12 +174,15 @@ void ClientMapEntryUpdater::RenderFrameCreated(RenderFrameHost* rfh) {
IoThreadClientData client_data; IoThreadClientData client_data;
client_data.io_thread_client = jdelegate_; client_data.io_thread_client = jdelegate_;
client_data.pending_association = false; client_data.pending_association = false;
RfhToIoThreadClientMap::GetInstance()->Set( RfhToIoThreadClientMap::GetInstance()->Set(GetRenderFrameHostIdPair(rfh),
GetRenderFrameHostIdPair(rfh), client_data); client_data);
RfhToIoThreadClientMap::GetInstance()->Set(rfh->GetFrameTreeNodeId(),
client_data);
} }
void ClientMapEntryUpdater::RenderFrameDeleted(RenderFrameHost* rfh) { void ClientMapEntryUpdater::RenderFrameDeleted(RenderFrameHost* rfh) {
RfhToIoThreadClientMap::GetInstance()->Erase(GetRenderFrameHostIdPair(rfh)); RfhToIoThreadClientMap::GetInstance()->Erase(GetRenderFrameHostIdPair(rfh));
RfhToIoThreadClientMap::GetInstance()->Erase(rfh->GetFrameTreeNodeId());
} }
void ClientMapEntryUpdater::WebContentsDestroyed() { void ClientMapEntryUpdater::WebContentsDestroyed() {
...@@ -175,6 +211,22 @@ std::unique_ptr<AwContentsIoThreadClient> AwContentsIoThreadClient::FromID( ...@@ -175,6 +211,22 @@ std::unique_ptr<AwContentsIoThreadClient> AwContentsIoThreadClient::FromID(
java_delegate)); java_delegate));
} }
std::unique_ptr<AwContentsIoThreadClient> AwContentsIoThreadClient::FromID(
int frame_tree_node_id) {
IoThreadClientData client_data;
if (!RfhToIoThreadClientMap::GetInstance()->Get(frame_tree_node_id,
&client_data))
return std::unique_ptr<AwContentsIoThreadClient>();
JNIEnv* env = AttachCurrentThread();
ScopedJavaLocalRef<jobject> java_delegate =
client_data.io_thread_client.get(env);
DCHECK(!client_data.pending_association || java_delegate.is_null());
return std::unique_ptr<AwContentsIoThreadClient>(
new AwContentsIoThreadClientImpl(client_data.pending_association,
java_delegate));
}
// static // static
void AwContentsIoThreadClient::SubFrameCreated(int render_process_id, void AwContentsIoThreadClient::SubFrameCreated(int render_process_id,
int parent_render_frame_id, int parent_render_frame_id,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment