Index: android_webview/native/aw_contents_io_thread_client_impl.cc |
diff --git a/android_webview/native/aw_contents_io_thread_client_impl.cc b/android_webview/native/aw_contents_io_thread_client_impl.cc |
index e1bc3490ba12491eaf72ac985384179919192a2e..1f86f0c19e9c31fbda0cabffc04502e998b1b830 100644 |
--- a/android_webview/native/aw_contents_io_thread_client_impl.cc |
+++ b/android_webview/native/aw_contents_io_thread_client_impl.cc |
@@ -57,6 +57,9 @@ IoThreadClientData::IoThreadClientData() : pending_association(false) {} |
typedef map<pair<int, int>, IoThreadClientData> |
RenderFrameHostToIoThreadClientType; |
+// Needed for PlzNavigate. |
jam
2017/03/09 22:13:05
nit: expand on the comment to explain why navigati
sgurun-gerrit only
2017/03/10 18:40:58
Done.
|
+typedef map<int, IoThreadClientData> FrameTreeNodeToIoThreadClientType; |
+ |
static pair<int, int> GetRenderFrameHostIdPair(RenderFrameHost* rfh) { |
return pair<int, int>(rfh->GetProcess()->GetID(), rfh->GetRoutingID()); |
} |
@@ -69,9 +72,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 +118,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 +172,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 +209,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, |