Add adoption of WebContents to Browser.

BUG=107201
TEST=no change

Review URL: https://chromiumcodereview.appspot.com/10891030

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@154211 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc
index a7038e4..5313700 100644
--- a/chrome/browser/ui/browser.cc
+++ b/chrome/browser/ui/browser.cc
@@ -93,7 +93,6 @@
 #include "chrome/browser/themes/theme_service.h"
 #include "chrome/browser/themes/theme_service_factory.h"
 #include "chrome/browser/ui/app_modal_dialogs/javascript_dialog_creator.h"
-#include "chrome/browser/ui/blocked_content/blocked_content_tab_helper.h"
 #include "chrome/browser/ui/bookmarks/bookmark_tab_helper.h"
 #include "chrome/browser/ui/browser_command_controller.h"
 #include "chrome/browser/ui/browser_commands.h"
@@ -111,7 +110,6 @@
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/chrome_pages.h"
 #include "chrome/browser/ui/chrome_select_file_policy.h"
-#include "chrome/browser/ui/constrained_window_tab_helper.h"
 #include "chrome/browser/ui/extensions/shell_window.h"
 #include "chrome/browser/ui/find_bar/find_bar.h"
 #include "chrome/browser/ui/find_bar/find_bar_controller.h"
@@ -129,7 +127,6 @@
 #include "chrome/browser/ui/search/search.h"
 #include "chrome/browser/ui/search/search_delegate.h"
 #include "chrome/browser/ui/search/search_model.h"
-#include "chrome/browser/ui/search_engines/search_engine_tab_helper.h"
 #include "chrome/browser/ui/singleton_tabs.h"
 #include "chrome/browser/ui/status_bubble.h"
 #include "chrome/browser/ui/sync/browser_synced_window_delegate.h"
@@ -143,7 +140,6 @@
 #include "chrome/browser/ui/webui/signin/login_ui_service.h"
 #include "chrome/browser/ui/webui/signin/login_ui_service_factory.h"
 #include "chrome/browser/ui/window_sizer/window_sizer.h"
-#include "chrome/browser/ui/zoom/zoom_controller.h"
 #include "chrome/browser/upgrade_detector.h"
 #include "chrome/browser/web_applications/web_app.h"
 #include "chrome/common/chrome_constants.h"
@@ -1025,7 +1021,7 @@
 void Browser::TabInsertedAt(TabContents* contents,
                             int index,
                             bool foreground) {
-  SetAsDelegate(contents, this);
+  SetAsDelegate(contents->web_contents(), this);
   contents->session_tab_helper()->SetWindowID(session_id());
 
   SyncHistoryWithTabs(index);
@@ -1052,7 +1048,7 @@
       content::NotificationService::NoDetails());
 
   // Sever the WebContents' connection back to us.
-  SetAsDelegate(contents, NULL);
+  SetAsDelegate(contents->web_contents(), NULL);
 }
 
 void Browser::TabDetachedAt(TabContents* contents, int index) {
@@ -1516,12 +1512,11 @@
                                  int64 source_frame_id,
                                  const GURL& target_url,
                                  WebContents* new_contents) {
-  // Create a TabContents now, so all observers are in place, as the network
+  // Adopt the WebContents now, so all observers are in place, as the network
   // requests for its initial navigation will start immediately. The WebContents
   // will later be inserted into this browser using Browser::Navigate via
-  // AddNewContents. The latter will retrieve the newly created TabContents from
-  // WebContents object.
-  TabContents::Factory::CreateTabContents(new_contents);
+  // AddNewContents.
+  AdoptAsTabContents(new_contents);
 
   // Notify.
   RetargetingDetails details;
@@ -2118,19 +2113,6 @@
 ///////////////////////////////////////////////////////////////////////////////
 // Browser, Assorted utility functions (private):
 
-void Browser::SetAsDelegate(TabContents* tab, Browser* delegate) {
-  // WebContents...
-  tab->web_contents()->SetDelegate(delegate);
-
-  // ...and all the helpers.
-  tab->blocked_content_tab_helper()->set_delegate(delegate);
-  tab->bookmark_tab_helper()->set_delegate(delegate);
-  tab->zoom_controller()->set_observer(delegate);
-  tab->constrained_window_tab_helper()->set_delegate(delegate);
-  tab->core_tab_helper()->set_delegate(delegate);
-  tab->search_engine_tab_helper()->set_delegate(delegate);
-}
-
 void Browser::CloseFrame() {
   window_->Close();
 }
@@ -2152,7 +2134,7 @@
       SyncHistoryWithTabs(0);
   }
 
-  SetAsDelegate(contents, NULL);
+  SetAsDelegate(contents->web_contents(), NULL);
   RemoveScheduledUpdatesFor(contents->web_contents());
 
   if (find_bar_controller_.get() && index == active_index()) {
diff --git a/chrome/browser/ui/browser.h b/chrome/browser/ui/browser.h
index 1899df1..12d5bb2 100644
--- a/chrome/browser/ui/browser.h
+++ b/chrome/browser/ui/browser.h
@@ -744,11 +744,19 @@
   // Returns true if the window can close, false otherwise.
   bool CanCloseWithInProgressDownloads();
 
-  // Assorted utility functions ///////////////////////////////////////////////
+  // Adoption functions ////////////////////////////////////////////////////////
 
-  // Sets the delegate of all the parts of the TabContents that
-  // are needed.
-  void SetAsDelegate(TabContents* tab, Browser* delegate);
+  // Adopts the specified WebContents as a full-fledged browser tab, attaching
+  // all the associated tab helpers that are needed for the WebContents to
+  // serve in that role. It is safe to call this on a WebContents that was
+  // already adopted.
+  static void AdoptAsTabContents(content::WebContents* web_contents);
+
+  // Sets the specified browser as the delegate of all the parts of the
+  // TabContents that are needed.
+  void SetAsDelegate(content::WebContents* web_contents, Browser* delegate);
+
+  // Assorted utility functions ///////////////////////////////////////////////
 
   // Shows the Find Bar, optionally selecting the next entry that matches the
   // existing search string for that Tab. |forward_direction| controls the
diff --git a/chrome/browser/ui/browser_adoption.cc b/chrome/browser/ui/browser_adoption.cc
new file mode 100644
index 0000000..ec48871
--- /dev/null
+++ b/chrome/browser/ui/browser_adoption.cc
@@ -0,0 +1,53 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/browser.h"
+
+#include "chrome/browser/ui/blocked_content/blocked_content_tab_helper.h"
+#include "chrome/browser/ui/bookmarks/bookmark_tab_helper.h"
+#include "chrome/browser/ui/constrained_window_tab_helper.h"
+#include "chrome/browser/ui/search_engines/search_engine_tab_helper.h"
+#include "chrome/browser/ui/tab_contents/core_tab_helper.h"
+#include "chrome/browser/ui/tab_contents/tab_contents.h"
+#include "chrome/browser/ui/zoom/zoom_controller.h"
+#include "content/public/browser/web_contents.h"
+
+using content::WebContents;
+
+namespace {
+
+const char kWebDialogDelegateUserDataKey[] = "BrowserAdoptedAsTabContents";
+
+}  // namespace
+
+// static
+void Browser::AdoptAsTabContents(WebContents* web_contents) {
+  // If already adopted, nothing to be done.
+  base::SupportsUserData::Data* adoption_tag =
+      web_contents->GetUserData(&kWebDialogDelegateUserDataKey);
+  if (adoption_tag)
+    return;
+
+  // Mark as adopted.
+  web_contents->SetUserData(&kWebDialogDelegateUserDataKey,
+                            new base::SupportsUserData::Data());
+
+  // Create all the tab helpers.
+  TabContents::Factory::CreateTabContents(web_contents);
+  // ... more tab helper creation goes here ...
+}
+
+void Browser::SetAsDelegate(WebContents* web_contents, Browser* delegate) {
+  // WebContents...
+  web_contents->SetDelegate(delegate);
+
+  // ...and all the helpers.
+  TabContents* tab = TabContents::FromWebContents(web_contents);
+  tab->blocked_content_tab_helper()->set_delegate(delegate);
+  tab->bookmark_tab_helper()->set_delegate(delegate);
+  tab->constrained_window_tab_helper()->set_delegate(delegate);
+  tab->core_tab_helper()->set_delegate(delegate);
+  tab->search_engine_tab_helper()->set_delegate(delegate);
+  tab->zoom_controller()->set_observer(delegate);
+}