| 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" |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 67 int embedder_render_process_id, | 67 int embedder_render_process_id, |
| 68 int embedder_routing_id, | 68 int embedder_routing_id, |
| 69 int element_instance_id, | 69 int element_instance_id, |
| 70 int guest_instance_id, | 70 int guest_instance_id, |
| 71 const base::DictionaryValue& attach_params) { | 71 const base::DictionaryValue& attach_params) { |
| 72 content::WebContents* guest_web_contents = | 72 content::WebContents* guest_web_contents = |
| 73 GetGuestByInstanceIDSafely(guest_instance_id, embedder_render_process_id); | 73 GetGuestByInstanceIDSafely(guest_instance_id, embedder_render_process_id); |
| 74 if (!guest_web_contents) | 74 if (!guest_web_contents) |
| 75 return; | 75 return; |
| 76 | 76 |
| 77 GuestViewBase* guest_view = | 77 auto guest_view = GuestViewBase::FromWebContents(guest_web_contents); |
| 78 GuestViewBase::FromWebContents(guest_web_contents); | |
| 79 DCHECK(guest_view); | 78 DCHECK(guest_view); |
| 80 | 79 |
| 81 content::RenderViewHost* rvh = | 80 auto rvh = content::RenderViewHost::FromID(embedder_render_process_id, |
| 82 content::RenderViewHost::FromID(embedder_render_process_id, | 81 embedder_routing_id); |
| 83 embedder_routing_id); | |
| 84 // We need to check that rvh is not NULL because there may be a race between | 82 // We need to check that rvh is not NULL because there may be a race between |
| 85 // AttachGuest and destroying the embedder (i.e. when the embedder is | 83 // AttachGuest and destroying the embedder (i.e. when the embedder is |
| 86 // destroyed immediately after the guest is created). | 84 // destroyed immediately after the guest is created). |
| 87 if (!rvh) | 85 if (!rvh) |
| 88 return; | 86 return; |
| 89 content::WebContents* owner_web_contents = | 87 auto owner_web_contents = content::WebContents::FromRenderViewHost(rvh); |
| 90 content::WebContents::FromRenderViewHost(rvh); | |
| 91 if (!owner_web_contents) | 88 if (!owner_web_contents) |
| 92 return; | 89 return; |
| 93 ElementInstanceKey key(owner_web_contents, element_instance_id); | 90 ElementInstanceKey key(owner_web_contents, element_instance_id); |
| 94 | 91 |
| 95 GuestInstanceIDMap::iterator it = instance_id_map_.find(key); | 92 auto it = instance_id_map_.find(key); |
| 96 if (it != instance_id_map_.end()) { | 93 if (it != instance_id_map_.end()) { |
| 97 int old_guest_instance_id = it->second; | 94 int old_guest_instance_id = it->second; |
| 98 // Reattachment to the same guest is not currently supported. | 95 // Reattachment to the same guest is not currently supported. |
| 99 if (old_guest_instance_id == guest_instance_id) | 96 if (old_guest_instance_id == guest_instance_id) |
| 100 return; | 97 return; |
| 101 | 98 |
| 102 content::WebContents* old_guest_web_contents = | 99 auto old_guest_web_contents = |
| 103 GetGuestByInstanceIDSafely(old_guest_instance_id, | 100 GetGuestByInstanceIDSafely(old_guest_instance_id, |
| 104 embedder_render_process_id); | 101 embedder_render_process_id); |
| 105 if (!old_guest_web_contents) | 102 if (!old_guest_web_contents) |
| 106 return; | 103 return; |
| 107 | 104 |
| 108 GuestViewBase* old_guest_view = | 105 auto old_guest_view = |
| 109 GuestViewBase::FromWebContents(old_guest_web_contents); | 106 GuestViewBase::FromWebContents(old_guest_web_contents); |
| 110 | 107 |
| 111 old_guest_view->Destroy(); | 108 old_guest_view->Destroy(); |
| 112 } | 109 } |
| 113 instance_id_map_[key] = guest_instance_id; | 110 instance_id_map_[key] = guest_instance_id; |
| 114 reverse_instance_id_map_[guest_instance_id] = key; | 111 reverse_instance_id_map_[guest_instance_id] = key; |
| 115 guest_view->SetAttachParams(attach_params); | 112 guest_view->SetAttachParams(attach_params); |
| 116 } | 113 } |
| 117 | 114 |
| 118 void GuestViewManager::DetachGuest(GuestViewBase* guest, | 115 void GuestViewManager::DetachGuest(GuestViewBase* guest, |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 183 element_instance_id); | 180 element_instance_id); |
| 184 if (guest_instance_id == guestview::kInstanceIDNone) | 181 if (guest_instance_id == guestview::kInstanceIDNone) |
| 185 return NULL; | 182 return NULL; |
| 186 | 183 |
| 187 return GetGuestByInstanceID(guest_instance_id); | 184 return GetGuestByInstanceID(guest_instance_id); |
| 188 } | 185 } |
| 189 | 186 |
| 190 int GuestViewManager::GetGuestInstanceIDForElementID( | 187 int GuestViewManager::GetGuestInstanceIDForElementID( |
| 191 content::WebContents* owner_web_contents, | 188 content::WebContents* owner_web_contents, |
| 192 int element_instance_id) { | 189 int element_instance_id) { |
| 193 GuestInstanceIDMap::iterator iter = instance_id_map_.find( | 190 auto iter = instance_id_map_.find( |
| 194 ElementInstanceKey(owner_web_contents, element_instance_id)); | 191 ElementInstanceKey(owner_web_contents, element_instance_id)); |
| 195 if (iter == instance_id_map_.end()) | 192 if (iter == instance_id_map_.end()) |
| 196 return guestview::kInstanceIDNone; | 193 return guestview::kInstanceIDNone; |
| 197 return iter->second; | 194 return iter->second; |
| 198 } | 195 } |
| 199 | 196 |
| 200 SiteInstance* GuestViewManager::GetGuestSiteInstance( | 197 SiteInstance* GuestViewManager::GetGuestSiteInstance( |
| 201 const GURL& guest_site) { | 198 const GURL& guest_site) { |
| 202 for (GuestInstanceMap::const_iterator it = | 199 for (auto it = guest_web_contents_by_instance_id_.begin(); |
| 203 guest_web_contents_by_instance_id_.begin(); | |
| 204 it != guest_web_contents_by_instance_id_.end(); ++it) { | 200 it != guest_web_contents_by_instance_id_.end(); ++it) { |
| 205 if (it->second->GetSiteInstance()->GetSiteURL() == guest_site) | 201 if (it->second->GetSiteInstance()->GetSiteURL() == guest_site) |
| 206 return it->second->GetSiteInstance(); | 202 return it->second->GetSiteInstance(); |
| 207 } | 203 } |
| 208 return NULL; | 204 return NULL; |
| 209 } | 205 } |
| 210 | 206 |
| 211 bool GuestViewManager::ForEachGuest(WebContents* owner_web_contents, | 207 bool GuestViewManager::ForEachGuest(WebContents* owner_web_contents, |
| 212 const GuestCallback& callback) { | 208 const GuestCallback& callback) { |
| 213 for (GuestInstanceMap::iterator it = | 209 for (auto it = guest_web_contents_by_instance_id_.begin(); |
| 214 guest_web_contents_by_instance_id_.begin(); | |
| 215 it != guest_web_contents_by_instance_id_.end(); ++it) { | 210 it != guest_web_contents_by_instance_id_.end(); ++it) { |
| 216 WebContents* guest = it->second; | 211 WebContents* guest = it->second; |
| 217 GuestViewBase* guest_view = GuestViewBase::FromWebContents(guest); | 212 auto guest_view = GuestViewBase::FromWebContents(guest); |
| 218 if (owner_web_contents != guest_view->owner_web_contents()) | 213 if (owner_web_contents != guest_view->owner_web_contents()) |
| 219 continue; | 214 continue; |
| 220 | 215 |
| 221 if (callback.Run(guest)) | 216 if (callback.Run(guest)) |
| 222 return true; | 217 return true; |
| 223 } | 218 } |
| 224 return false; | 219 return false; |
| 225 } | 220 } |
| 226 | 221 |
| 227 void GuestViewManager::AddGuest(int guest_instance_id, | 222 void GuestViewManager::AddGuest(int guest_instance_id, |
| 228 WebContents* guest_web_contents) { | 223 WebContents* guest_web_contents) { |
| 229 CHECK(!ContainsKey(guest_web_contents_by_instance_id_, guest_instance_id)); | 224 CHECK(!ContainsKey(guest_web_contents_by_instance_id_, guest_instance_id)); |
| 230 CHECK(CanUseGuestInstanceID(guest_instance_id)); | 225 CHECK(CanUseGuestInstanceID(guest_instance_id)); |
| 231 guest_web_contents_by_instance_id_[guest_instance_id] = guest_web_contents; | 226 guest_web_contents_by_instance_id_[guest_instance_id] = guest_web_contents; |
| 232 } | 227 } |
| 233 | 228 |
| 234 void GuestViewManager::RemoveGuest(int guest_instance_id) { | 229 void GuestViewManager::RemoveGuest(int guest_instance_id) { |
| 235 GuestInstanceMap::iterator it = | 230 auto it = guest_web_contents_by_instance_id_.find(guest_instance_id); |
| 236 guest_web_contents_by_instance_id_.find(guest_instance_id); | |
| 237 DCHECK(it != guest_web_contents_by_instance_id_.end()); | 231 DCHECK(it != guest_web_contents_by_instance_id_.end()); |
| 238 guest_web_contents_by_instance_id_.erase(it); | 232 guest_web_contents_by_instance_id_.erase(it); |
| 239 | 233 |
| 240 GuestInstanceIDReverseMap::iterator id_iter = | 234 auto id_iter = reverse_instance_id_map_.find(guest_instance_id); |
| 241 reverse_instance_id_map_.find(guest_instance_id); | |
| 242 if (id_iter != reverse_instance_id_map_.end()) { | 235 if (id_iter != reverse_instance_id_map_.end()) { |
| 243 const ElementInstanceKey& instance_id_key = id_iter->second; | 236 const ElementInstanceKey& instance_id_key = id_iter->second; |
| 244 instance_id_map_.erase(instance_id_map_.find(instance_id_key)); | 237 instance_id_map_.erase(instance_id_map_.find(instance_id_key)); |
| 245 reverse_instance_id_map_.erase(id_iter); | 238 reverse_instance_id_map_.erase(id_iter); |
| 246 } | 239 } |
| 247 | 240 |
| 248 // All the instance IDs that lie within [0, last_instance_id_removed_] | 241 // All the instance IDs that lie within [0, last_instance_id_removed_] |
| 249 // are invalid. | 242 // are invalid. |
| 250 // The remaining sparse invalid IDs are kept in |removed_instance_ids_| set. | 243 // The remaining sparse invalid IDs are kept in |removed_instance_ids_| set. |
| 251 // The following code compacts the set by incrementing | 244 // The following code compacts the set by incrementing |
| 252 // |last_instance_id_removed_|. | 245 // |last_instance_id_removed_|. |
| 253 if (guest_instance_id == last_instance_id_removed_ + 1) { | 246 if (guest_instance_id == last_instance_id_removed_ + 1) { |
| 254 ++last_instance_id_removed_; | 247 ++last_instance_id_removed_; |
| 255 // Compact. | 248 // Compact. |
| 256 std::set<int>::iterator iter = removed_instance_ids_.begin(); | 249 auto iter = removed_instance_ids_.begin(); |
| 257 while (iter != removed_instance_ids_.end()) { | 250 while (iter != removed_instance_ids_.end()) { |
| 258 int instance_id = *iter; | 251 int instance_id = *iter; |
| 259 // The sparse invalid IDs must not lie within | 252 // The sparse invalid IDs must not lie within |
| 260 // [0, last_instance_id_removed_] | 253 // [0, last_instance_id_removed_] |
| 261 DCHECK(instance_id > last_instance_id_removed_); | 254 DCHECK(instance_id > last_instance_id_removed_); |
| 262 if (instance_id != last_instance_id_removed_ + 1) | 255 if (instance_id != last_instance_id_removed_ + 1) |
| 263 break; | 256 break; |
| 264 ++last_instance_id_removed_; | 257 ++last_instance_id_removed_; |
| 265 removed_instance_ids_.erase(iter++); | 258 removed_instance_ids_.erase(iter++); |
| 266 } | 259 } |
| 267 } else { | 260 } else { |
| 268 removed_instance_ids_.insert(guest_instance_id); | 261 removed_instance_ids_.insert(guest_instance_id); |
| 269 } | 262 } |
| 270 } | 263 } |
| 271 | 264 |
| 272 content::WebContents* GuestViewManager::GetGuestByInstanceID( | 265 content::WebContents* GuestViewManager::GetGuestByInstanceID( |
| 273 int guest_instance_id) { | 266 int guest_instance_id) { |
| 274 GuestInstanceMap::const_iterator it = | 267 auto it = guest_web_contents_by_instance_id_.find(guest_instance_id); |
| 275 guest_web_contents_by_instance_id_.find(guest_instance_id); | |
| 276 if (it == guest_web_contents_by_instance_id_.end()) | 268 if (it == guest_web_contents_by_instance_id_.end()) |
| 277 return NULL; | 269 return NULL; |
| 278 return it->second; | 270 return it->second; |
| 279 } | 271 } |
| 280 | 272 |
| 281 bool GuestViewManager::CanEmbedderAccessInstanceIDMaybeKill( | 273 bool GuestViewManager::CanEmbedderAccessInstanceIDMaybeKill( |
| 282 int embedder_render_process_id, | 274 int embedder_render_process_id, |
| 283 int guest_instance_id) { | 275 int guest_instance_id) { |
| 284 if (!CanEmbedderAccessInstanceID(embedder_render_process_id, | 276 if (!CanEmbedderAccessInstanceID(embedder_render_process_id, |
| 285 guest_instance_id)) { | 277 guest_instance_id)) { |
| (...skipping 23 matching lines...) Expand all Loading... |
| 309 | 301 |
| 310 // The embedder is trying to access an instance ID that has not yet been | 302 // The embedder is trying to access an instance ID that has not yet been |
| 311 // allocated by GuestViewManager. This could cause instance ID | 303 // allocated by GuestViewManager. This could cause instance ID |
| 312 // collisions in the future, and potentially give one embedder access to a | 304 // collisions in the future, and potentially give one embedder access to a |
| 313 // guest it does not own. | 305 // guest it does not own. |
| 314 if (guest_instance_id > current_instance_id_) | 306 if (guest_instance_id > current_instance_id_) |
| 315 return false; | 307 return false; |
| 316 | 308 |
| 317 // We might get some late arriving messages at tear down. Let's let the | 309 // We might get some late arriving messages at tear down. Let's let the |
| 318 // embedder tear down in peace. | 310 // embedder tear down in peace. |
| 319 GuestInstanceMap::const_iterator it = | 311 auto it = guest_web_contents_by_instance_id_.find(guest_instance_id); |
| 320 guest_web_contents_by_instance_id_.find(guest_instance_id); | |
| 321 if (it == guest_web_contents_by_instance_id_.end()) | 312 if (it == guest_web_contents_by_instance_id_.end()) |
| 322 return true; | 313 return true; |
| 323 | 314 |
| 324 GuestViewBase* guest_view = GuestViewBase::FromWebContents(it->second); | 315 auto guest_view = GuestViewBase::FromWebContents(it->second); |
| 325 if (!guest_view) | 316 if (!guest_view) |
| 326 return false; | 317 return false; |
| 327 | 318 |
| 328 return embedder_render_process_id == | 319 return embedder_render_process_id == |
| 329 guest_view->owner_web_contents()->GetRenderProcessHost()->GetID(); | 320 guest_view->owner_web_contents()->GetRenderProcessHost()->GetID(); |
| 330 } | 321 } |
| 331 | 322 |
| 332 } // namespace extensions | 323 } // namespace extensions |
| OLD | NEW |