Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(35)

Side by Side Diff: extensions/browser/guest_view/guest_view_manager.cc

Issue 921473006: GuestView: Fix message routing across embedder navigations (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Updated comments CQ'ing Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "extensions/browser/guest_view/guest_view_manager.h" 5 #include "extensions/browser/guest_view/guest_view_manager.h"
6 6
7 #include "base/strings/stringprintf.h" 7 #include "base/strings/stringprintf.h"
8 #include "content/public/browser/browser_context.h" 8 #include "content/public/browser/browser_context.h"
9 #include "content/public/browser/render_frame_host.h" 9 #include "content/public/browser/render_frame_host.h"
10 #include "content/public/browser/render_process_host.h" 10 #include "content/public/browser/render_process_host.h"
11 #include "content/public/browser/render_view_host.h" 11 #include "content/public/browser/render_view_host.h"
12 #include "content/public/browser/user_metrics.h" 12 #include "content/public/browser/user_metrics.h"
13 #include "content/public/browser/web_contents_observer.h" 13 #include "content/public/browser/web_contents_observer.h"
14 #include "content/public/common/child_process_host.h"
14 #include "content/public/common/result_codes.h" 15 #include "content/public/common/result_codes.h"
15 #include "content/public/common/url_constants.h" 16 #include "content/public/common/url_constants.h"
16 #include "extensions/browser/extension_system.h" 17 #include "extensions/browser/extension_system.h"
17 #include "extensions/browser/guest_view/guest_view_base.h" 18 #include "extensions/browser/guest_view/guest_view_base.h"
18 #include "extensions/browser/guest_view/guest_view_manager_factory.h" 19 #include "extensions/browser/guest_view/guest_view_manager_factory.h"
19 #include "extensions/common/extension_messages.h" 20 #include "extensions/common/extension_messages.h"
20 #include "extensions/common/guest_view/guest_view_constants.h" 21 #include "extensions/common/guest_view/guest_view_constants.h"
21 #include "net/base/escape.h" 22 #include "net/base/escape.h"
22 #include "url/gurl.h" 23 #include "url/gurl.h"
23 24
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
63 content::WebContents* GuestViewManager::GetGuestByInstanceIDSafely( 64 content::WebContents* GuestViewManager::GetGuestByInstanceIDSafely(
64 int guest_instance_id, 65 int guest_instance_id,
65 int embedder_render_process_id) { 66 int embedder_render_process_id) {
66 if (!CanEmbedderAccessInstanceIDMaybeKill(embedder_render_process_id, 67 if (!CanEmbedderAccessInstanceIDMaybeKill(embedder_render_process_id,
67 guest_instance_id)) { 68 guest_instance_id)) {
68 return nullptr; 69 return nullptr;
69 } 70 }
70 return GetGuestByInstanceID(guest_instance_id); 71 return GetGuestByInstanceID(guest_instance_id);
71 } 72 }
72 73
73 void GuestViewManager::AttachGuest( 74 void GuestViewManager::AttachGuest(int embedder_process_id,
74 int embedder_render_process_id, 75 int element_instance_id,
75 int embedder_routing_id, 76 int guest_instance_id,
76 int element_instance_id, 77 const base::DictionaryValue& attach_params) {
77 int guest_instance_id, 78 auto guest_view = GuestViewBase::From(embedder_process_id, guest_instance_id);
78 const base::DictionaryValue& attach_params) { 79 if (!guest_view)
79 content::WebContents* guest_web_contents =
80 GetGuestByInstanceIDSafely(guest_instance_id, embedder_render_process_id);
81 if (!guest_web_contents)
82 return; 80 return;
83 81
84 auto guest_view = GuestViewBase::FromWebContents(guest_web_contents); 82 ElementInstanceKey key(embedder_process_id, element_instance_id);
85 DCHECK(guest_view);
86
87 auto rvh = content::RenderViewHost::FromID(embedder_render_process_id,
88 embedder_routing_id);
89 // We need to check that rvh is not nullptr because there may be a race
90 // between AttachGuest and destroying the embedder (i.e. when the embedder is
91 // destroyed immediately after the guest is created).
92 if (!rvh)
93 return;
94 auto owner_web_contents = content::WebContents::FromRenderViewHost(rvh);
95 if (!owner_web_contents)
96 return;
97 ElementInstanceKey key(owner_web_contents, element_instance_id);
98
99 auto it = instance_id_map_.find(key); 83 auto it = instance_id_map_.find(key);
84 // If there is an existing guest attached to the element, then destroy the
85 // existing guest.
100 if (it != instance_id_map_.end()) { 86 if (it != instance_id_map_.end()) {
101 int old_guest_instance_id = it->second; 87 int old_guest_instance_id = it->second;
102 // Reattachment to the same guest is not currently supported.
103 if (old_guest_instance_id == guest_instance_id) 88 if (old_guest_instance_id == guest_instance_id)
104 return; 89 return;
105 90
106 auto old_guest_web_contents = 91 auto old_guest_view = GuestViewBase::From(embedder_process_id,
107 GetGuestByInstanceIDSafely(old_guest_instance_id, 92 old_guest_instance_id);
108 embedder_render_process_id);
109 if (!old_guest_web_contents)
110 return;
111
112 auto old_guest_view =
113 GuestViewBase::FromWebContents(old_guest_web_contents);
114
115 old_guest_view->Destroy(); 93 old_guest_view->Destroy();
116 } 94 }
117 instance_id_map_[key] = guest_instance_id; 95 instance_id_map_[key] = guest_instance_id;
118 reverse_instance_id_map_[guest_instance_id] = key; 96 reverse_instance_id_map_[guest_instance_id] = key;
119 guest_view->SetAttachParams(attach_params); 97 guest_view->SetAttachParams(attach_params);
120 } 98 }
121 99
122 void GuestViewManager::DetachGuest(GuestViewBase* guest, 100 void GuestViewManager::DetachGuest(GuestViewBase* guest) {
123 int element_instance_id) {
124 if (!guest->attached()) 101 if (!guest->attached())
125 return; 102 return;
126 103
127 ElementInstanceKey key(guest->owner_web_contents(), element_instance_id); 104 auto reverse_it = reverse_instance_id_map_.find(guest->guest_instance_id());
128 auto it = instance_id_map_.find(key); 105 if (reverse_it == reverse_instance_id_map_.end())
129 // There's nothing to do if this key does not exist in the map.
130 if (it == instance_id_map_.end())
131 return; 106 return;
132 107
133 int guest_instance_id = it->second; 108 const ElementInstanceKey& key = reverse_it->second;
134 instance_id_map_.erase(key);
135 109
136 auto reverse_it = reverse_instance_id_map_.find(guest->guest_instance_id()); 110 auto it = instance_id_map_.find(key);
137 DCHECK(reverse_it != reverse_instance_id_map_.end()); 111 DCHECK(it != instance_id_map_.end());
138 DCHECK(reverse_it->second == key); 112
139 reverse_instance_id_map_.erase(guest_instance_id); 113 reverse_instance_id_map_.erase(reverse_it);
114 instance_id_map_.erase(it);
140 } 115 }
141 116
142 int GuestViewManager::GetNextInstanceID() { 117 int GuestViewManager::GetNextInstanceID() {
143 return ++current_instance_id_; 118 return ++current_instance_id_;
144 } 119 }
145 120
146 void GuestViewManager::CreateGuest(const std::string& view_type, 121 void GuestViewManager::CreateGuest(const std::string& view_type,
147 content::WebContents* owner_web_contents, 122 content::WebContents* owner_web_contents,
148 const base::DictionaryValue& create_params, 123 const base::DictionaryValue& create_params,
149 const WebContentsCreatedCallback& callback) { 124 const WebContentsCreatedCallback& callback) {
(...skipping 13 matching lines...) Expand all
163 if (!guest) 138 if (!guest)
164 return nullptr; 139 return nullptr;
165 content::WebContents::CreateParams guest_create_params(create_params); 140 content::WebContents::CreateParams guest_create_params(create_params);
166 guest_create_params.guest_delegate = guest; 141 guest_create_params.guest_delegate = guest;
167 auto guest_web_contents = WebContents::Create(guest_create_params); 142 auto guest_web_contents = WebContents::Create(guest_create_params);
168 guest->InitWithWebContents(base::DictionaryValue(), guest_web_contents); 143 guest->InitWithWebContents(base::DictionaryValue(), guest_web_contents);
169 return guest_web_contents; 144 return guest_web_contents;
170 } 145 }
171 146
172 content::WebContents* GuestViewManager::GetGuestByInstanceID( 147 content::WebContents* GuestViewManager::GetGuestByInstanceID(
173 content::WebContents* owner_web_contents, 148 int owner_process_id,
174 int element_instance_id) { 149 int element_instance_id) {
175 int guest_instance_id = GetGuestInstanceIDForElementID(owner_web_contents, 150 int guest_instance_id = GetGuestInstanceIDForElementID(owner_process_id,
176 element_instance_id); 151 element_instance_id);
177 if (guest_instance_id == guestview::kInstanceIDNone) 152 if (guest_instance_id == guestview::kInstanceIDNone)
178 return nullptr; 153 return nullptr;
179 154
180 return GetGuestByInstanceID(guest_instance_id); 155 return GetGuestByInstanceID(guest_instance_id);
181 } 156 }
182 157
183 int GuestViewManager::GetGuestInstanceIDForElementID( 158 int GuestViewManager::GetGuestInstanceIDForElementID(int owner_process_id,
184 content::WebContents* owner_web_contents, 159 int element_instance_id) {
185 int element_instance_id) {
186 auto iter = instance_id_map_.find( 160 auto iter = instance_id_map_.find(
187 ElementInstanceKey(owner_web_contents, element_instance_id)); 161 ElementInstanceKey(owner_process_id, element_instance_id));
188 if (iter == instance_id_map_.end()) 162 if (iter == instance_id_map_.end())
189 return guestview::kInstanceIDNone; 163 return guestview::kInstanceIDNone;
190 return iter->second; 164 return iter->second;
191 } 165 }
192 166
193 SiteInstance* GuestViewManager::GetGuestSiteInstance( 167 SiteInstance* GuestViewManager::GetGuestSiteInstance(
194 const GURL& guest_site) { 168 const GURL& guest_site) {
195 for (const auto& guest : guest_web_contents_by_instance_id_) { 169 for (const auto& guest : guest_web_contents_by_instance_id_) {
196 if (guest.second->GetSiteInstance()->GetSiteURL() == guest_site) 170 if (guest.second->GetSiteInstance()->GetSiteURL() == guest_site)
197 return guest.second->GetSiteInstance(); 171 return guest.second->GetSiteInstance();
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
306 return true; 280 return true;
307 281
308 auto guest_view = GuestViewBase::FromWebContents(it->second); 282 auto guest_view = GuestViewBase::FromWebContents(it->second);
309 if (!guest_view) 283 if (!guest_view)
310 return false; 284 return false;
311 285
312 return embedder_render_process_id == 286 return embedder_render_process_id ==
313 guest_view->owner_web_contents()->GetRenderProcessHost()->GetID(); 287 guest_view->owner_web_contents()->GetRenderProcessHost()->GetID();
314 } 288 }
315 289
290 GuestViewManager::ElementInstanceKey::ElementInstanceKey()
291 : embedder_process_id(content::ChildProcessHost::kInvalidUniqueID),
292 element_instance_id(content::ChildProcessHost::kInvalidUniqueID) {
293 }
294
295 GuestViewManager::ElementInstanceKey::ElementInstanceKey(
296 int embedder_process_id,
297 int element_instance_id)
298 : embedder_process_id(embedder_process_id),
299 element_instance_id(element_instance_id) {
300 }
301
302 bool GuestViewManager::ElementInstanceKey::operator<(
303 const GuestViewManager::ElementInstanceKey& other) const {
304 if (embedder_process_id != other.embedder_process_id)
305 return embedder_process_id < other.embedder_process_id;
306
307 return element_instance_id < other.element_instance_id;
308 }
309
310 bool GuestViewManager::ElementInstanceKey::operator==(
311 const GuestViewManager::ElementInstanceKey& other) const {
312 return (embedder_process_id == other.embedder_process_id) &&
313 (element_instance_id == other.element_instance_id);
314 }
315
316 } // namespace extensions 316 } // namespace extensions
OLDNEW
« no previous file with comments | « extensions/browser/guest_view/guest_view_manager.h ('k') | extensions/browser/guest_view/guest_view_message_filter.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698