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..38ee88f6f44915d2ae429df46c883a3fa72c4295 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,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, |