Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / extensions / browser / guest_view / guest_view_manager.cc
index 3a2412e..77a46c6 100644 (file)
@@ -7,14 +7,15 @@
 #include "base/strings/stringprintf.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/render_process_host.h"
+#include "content/public/browser/render_view_host.h"
 #include "content/public/browser/user_metrics.h"
 #include "content/public/browser/web_contents_observer.h"
 #include "content/public/common/result_codes.h"
 #include "content/public/common/url_constants.h"
 #include "extensions/browser/extension_system.h"
 #include "extensions/browser/guest_view/guest_view_base.h"
-#include "extensions/browser/guest_view/guest_view_constants.h"
 #include "extensions/browser/guest_view/guest_view_manager_factory.h"
+#include "extensions/common/guest_view/guest_view_constants.h"
 #include "net/base/escape.h"
 #include "url/gurl.h"
 
@@ -60,6 +61,53 @@ content::WebContents* GuestViewManager::GetGuestByInstanceIDSafely(
   return GetGuestByInstanceID(guest_instance_id);
 }
 
+void GuestViewManager::AttachGuest(
+    int embedder_render_process_id,
+    int embedder_routing_id,
+    int element_instance_id,
+    int guest_instance_id,
+    const base::DictionaryValue& attach_params) {
+  content::WebContents* guest_web_contents =
+      GetGuestByInstanceIDSafely(guest_instance_id, embedder_render_process_id);
+  if (!guest_web_contents)
+    return;
+
+  GuestViewBase* guest_view =
+      GuestViewBase::FromWebContents(guest_web_contents);
+  DCHECK(guest_view);
+
+  content::RenderViewHost* rvh =
+      content::RenderViewHost::FromID(embedder_render_process_id,
+                                      embedder_routing_id);
+  content::WebContents* embedder_web_contents =
+      content::WebContents::FromRenderViewHost(rvh);
+  if (!embedder_web_contents)
+    return;
+  ElementInstanceKey key(embedder_web_contents, element_instance_id);
+
+  GuestInstanceIDMap::iterator it = instance_id_map_.find(key);
+  if (it != instance_id_map_.end()) {
+    int old_guest_instance_id = it->second;
+    // Reattachment to the same guest is not currently supported.
+    if (old_guest_instance_id == guest_instance_id)
+      return;
+
+    content::WebContents* old_guest_web_contents =
+        GetGuestByInstanceIDSafely(old_guest_instance_id,
+                                   embedder_render_process_id);
+    if (!old_guest_web_contents)
+      return;
+
+    GuestViewBase* old_guest_view =
+        GuestViewBase::FromWebContents(old_guest_web_contents);
+
+    old_guest_view->Destroy();
+  }
+  instance_id_map_[key] = guest_instance_id;
+  reverse_instance_id_map_.insert(std::make_pair(guest_instance_id, key));
+  guest_view->SetAttachParams(attach_params);
+}
+
 int GuestViewManager::GetNextInstanceID() {
   return ++current_instance_id_;
 }
@@ -100,18 +148,25 @@ content::WebContents* GuestViewManager::CreateGuestWithWebContentsParams(
   return guest_web_contents;
 }
 
-void GuestViewManager::MaybeGetGuestByInstanceIDOrKill(
-    int guest_instance_id,
-    int embedder_render_process_id,
-    const GuestByInstanceIDCallback& callback) {
-  if (!CanEmbedderAccessInstanceIDMaybeKill(embedder_render_process_id,
-                                            guest_instance_id)) {
-    // If we kill the embedder, then don't bother calling back.
-    return;
-  }
-  content::WebContents* guest_web_contents =
-      GetGuestByInstanceID(guest_instance_id);
-  callback.Run(guest_web_contents);
+content::WebContents* GuestViewManager::GetGuestByInstanceID(
+    content::WebContents* embedder_web_contents,
+    int element_instance_id) {
+  int guest_instance_id = GetGuestInstanceIDForElementID(embedder_web_contents,
+                                                         element_instance_id);
+  if (guest_instance_id == guestview::kInstanceIDNone)
+    return NULL;
+
+  return GetGuestByInstanceID(guest_instance_id);
+}
+
+int GuestViewManager::GetGuestInstanceIDForElementID(
+    content::WebContents* embedder_web_contents,
+    int element_instance_id) {
+  GuestInstanceIDMap::iterator iter = instance_id_map_.find(
+      ElementInstanceKey(embedder_web_contents, element_instance_id));
+  if (iter == instance_id_map_.end())
+    return guestview::kInstanceIDNone;
+  return iter->second;
 }
 
 SiteInstance* GuestViewManager::GetGuestSiteInstance(
@@ -154,6 +209,14 @@ void GuestViewManager::RemoveGuest(int guest_instance_id) {
   DCHECK(it != guest_web_contents_by_instance_id_.end());
   guest_web_contents_by_instance_id_.erase(it);
 
+  GuestInstanceIDReverseMap::iterator id_iter =
+      reverse_instance_id_map_.find(guest_instance_id);
+  if (id_iter != reverse_instance_id_map_.end()) {
+    const ElementInstanceKey& instance_id_key = id_iter->second;
+    instance_id_map_.erase(instance_id_map_.find(instance_id_key));
+    reverse_instance_id_map_.erase(id_iter);
+  }
+
   // All the instance IDs that lie within [0, last_instance_id_removed_]
   // are invalid.
   // The remaining sparse invalid IDs are kept in |removed_instance_ids_| set.