OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |