| 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,
|
|
|