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 {
static std::unique_ptr<AwContentsIoThreadClient> FromID(int render_process_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.
// An empty scoped_ptr is a valid return value.
static std::unique_ptr<AwContentsIoThreadClient>
......
......@@ -18,6 +18,7 @@
#include "content/public/browser/resource_request_info.h"
#include "net/http/http_response_headers.h"
#include "net/url_request/url_request_job.h"
#include "url/url_constants.h"
namespace android_webview {
......@@ -119,13 +120,22 @@ std::unique_ptr<AwContentsIoThreadClient> GetCorrespondingIoThreadClient(
net::URLRequest* request) {
if (content::ResourceRequestInfo::OriginatedFromServiceWorker(request))
return AwContentsIoThreadClient::GetServiceWorkerIoThreadClient();
int render_process_id, render_frame_id;
if (!content::ResourceRequestInfo::GetRenderFrameForRequest(
request, &render_process_id, &render_frame_id)) {
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);
}
......@@ -144,6 +154,13 @@ net::URLRequestJob* AwRequestInterceptor::MaybeInterceptRequest(
if (request->GetUserData(kRequestAlreadyHasJobDataKey))
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 =
GetCorrespondingIoThreadClient(request);
......
......@@ -162,6 +162,16 @@ IoThreadClientThrottle::GetIoThreadClient() const {
if (content::ResourceRequestInfo::OriginatedFromServiceWorker(request_))
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_);
}
......
......@@ -57,6 +57,11 @@ IoThreadClientData::IoThreadClientData() : pending_association(false) {}
typedef map<pair<int, int>, IoThreadClientData>
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) {
return pair<int, int>(rfh->GetProcess()->GetID(), rfh->GetRoutingID());
}
......@@ -69,9 +74,14 @@ class RfhToIoThreadClientMap {
bool Get(pair<int, int> rfh_id, IoThreadClientData* client);
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:
base::Lock map_lock_;
RenderFrameHostToIoThreadClientType rfh_to_io_thread_client_;
FrameTreeNodeToIoThreadClientType frame_tree_node_to_io_thread_client_;
};
// static
......@@ -110,6 +120,29 @@ void RfhToIoThreadClientMap::Erase(pair<int, int> 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 ------------------------------------------------------
class ClientMapEntryUpdater : public content::WebContentsObserver {
......@@ -141,12 +174,15 @@ void ClientMapEntryUpdater::RenderFrameCreated(RenderFrameHost* rfh) {
IoThreadClientData client_data;
client_data.io_thread_client = jdelegate_;
client_data.pending_association = false;
RfhToIoThreadClientMap::GetInstance()->Set(
GetRenderFrameHostIdPair(rfh), client_data);
RfhToIoThreadClientMap::GetInstance()->Set(GetRenderFrameHostIdPair(rfh),
client_data);
RfhToIoThreadClientMap::GetInstance()->Set(rfh->GetFrameTreeNodeId(),
client_data);
}
void ClientMapEntryUpdater::RenderFrameDeleted(RenderFrameHost* rfh) {
RfhToIoThreadClientMap::GetInstance()->Erase(GetRenderFrameHostIdPair(rfh));
RfhToIoThreadClientMap::GetInstance()->Erase(rfh->GetFrameTreeNodeId());
}
void ClientMapEntryUpdater::WebContentsDestroyed() {
......@@ -175,6 +211,22 @@ std::unique_ptr<AwContentsIoThreadClient> AwContentsIoThreadClient::FromID(
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
void AwContentsIoThreadClient::SubFrameCreated(int render_process_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