diff options
Diffstat (limited to 'chrome/browser/ui/tab_contents/tab_contents.cc')
-rw-r--r-- | chrome/browser/ui/tab_contents/tab_contents.cc | 242 |
1 files changed, 242 insertions, 0 deletions
diff --git a/chrome/browser/ui/tab_contents/tab_contents.cc b/chrome/browser/ui/tab_contents/tab_contents.cc new file mode 100644 index 0000000..305df3d --- /dev/null +++ b/chrome/browser/ui/tab_contents/tab_contents.cc @@ -0,0 +1,242 @@ +// 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/tab_contents/tab_contents.h" + +#include "base/command_line.h" +#include "base/lazy_instance.h" +#include "chrome/browser/autocomplete_history_manager.h" +#include "chrome/browser/autofill/autofill_external_delegate.h" +#include "chrome/browser/autofill/autofill_manager.h" +#include "chrome/browser/automation/automation_tab_helper.h" +#include "chrome/browser/content_settings/tab_specific_content_settings.h" +#include "chrome/browser/extensions/api/web_navigation/web_navigation_api.h" +#include "chrome/browser/extensions/extension_tab_helper.h" +#include "chrome/browser/external_protocol/external_protocol_observer.h" +#include "chrome/browser/favicon/favicon_tab_helper.h" +#include "chrome/browser/history/history_tab_helper.h" +#include "chrome/browser/infobars/infobar_tab_helper.h" +#include "chrome/browser/omnibox_search_hint.h" +#include "chrome/browser/password_manager/password_manager.h" +#include "chrome/browser/password_manager/password_manager_delegate_impl.h" +#include "chrome/browser/plugin_observer.h" +#include "chrome/browser/prerender/prerender_tab_helper.h" +#include "chrome/browser/printing/print_preview_message_handler.h" +#include "chrome/browser/printing/print_view_manager.h" +#include "chrome/browser/safe_browsing/safe_browsing_tab_observer.h" +#include "chrome/browser/sessions/restore_tab_helper.h" +#include "chrome/browser/tab_contents/tab_contents_ssl_helper.h" +#include "chrome/browser/tab_contents/thumbnail_generator.h" +#include "chrome/browser/translate/translate_tab_helper.h" +#include "chrome/browser/ui/alternate_error_tab_observer.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/find_bar/find_tab_helper.h" +#include "chrome/browser/ui/hung_plugin_tab_helper.h" +#include "chrome/browser/ui/intents/web_intent_picker_controller.h" +#include "chrome/browser/ui/pdf/pdf_tab_observer.h" +#include "chrome/browser/ui/prefs/prefs_tab_helper.h" +#include "chrome/browser/ui/sad_tab_helper.h" +#include "chrome/browser/ui/search_engines/search_engine_tab_helper.h" +#include "chrome/browser/ui/snapshot_tab_helper.h" +#include "chrome/browser/ui/sync/one_click_signin_helper.h" +#include "chrome/browser/ui/sync/tab_contents_wrapper_synced_tab_delegate.h" +#include "chrome/browser/ui/tab_contents/core_tab_helper.h" +#include "chrome/browser/ui/zoom/zoom_controller.h" +#include "chrome/browser/view_type_utils.h" +#include "chrome/common/chrome_notification_types.h" +#include "chrome/common/chrome_switches.h" +#include "chrome/common/thumbnail_support.h" +#include "content/public/browser/notification_service.h" +#include "content/public/browser/web_contents.h" + +#if defined(OS_WIN) +#include "base/win/metro.h" +#endif + +using content::WebContents; + +namespace { + +static base::LazyInstance<base::PropertyAccessor<TabContents*> > + g_tab_contents_wrapper_property_accessor = LAZY_INSTANCE_INITIALIZER; + +} // namespace + +//////////////////////////////////////////////////////////////////////////////// +// TabContents, public: + +TabContents::TabContents(WebContents* contents) + : content::WebContentsObserver(contents), + in_destructor_(false), + web_contents_(contents) { + DCHECK(contents); + DCHECK(!GetCurrentWrapperForContents(contents)); + + chrome::SetViewType(contents, chrome::VIEW_TYPE_TAB_CONTENTS); + + // Stash this in the property bag so it can be retrieved without having to + // go to a Browser. + property_accessor()->SetProperty(contents->GetPropertyBag(), this); + + // Create the tab helpers. + autocomplete_history_manager_.reset(new AutocompleteHistoryManager(contents)); + autofill_manager_ = new AutofillManager(this); + if (CommandLine::ForCurrentProcess()->HasSwitch( + switches::kExternalAutofillPopup)) { + autofill_external_delegate_.reset( + AutofillExternalDelegate::Create(this, autofill_manager_.get())); + autofill_manager_->SetExternalDelegate(autofill_external_delegate_.get()); + autocomplete_history_manager_->SetExternalDelegate( + autofill_external_delegate_.get()); + } +#if defined(ENABLE_AUTOMATION) + automation_tab_helper_.reset(new AutomationTabHelper(contents)); +#endif + blocked_content_tab_helper_.reset(new BlockedContentTabHelper(this)); + bookmark_tab_helper_.reset(new BookmarkTabHelper(this)); + constrained_window_tab_helper_.reset(new ConstrainedWindowTabHelper(this)); + core_tab_helper_.reset(new CoreTabHelper(contents)); + extension_tab_helper_.reset(new ExtensionTabHelper(this)); + favicon_tab_helper_.reset(new FaviconTabHelper(contents)); + find_tab_helper_.reset(new FindTabHelper(contents)); + history_tab_helper_.reset(new HistoryTabHelper(contents)); + hung_plugin_tab_helper_.reset(new HungPluginTabHelper(contents)); + infobar_tab_helper_.reset(new InfoBarTabHelper(contents)); + password_manager_delegate_.reset(new PasswordManagerDelegateImpl(this)); + password_manager_.reset( + new PasswordManager(contents, password_manager_delegate_.get())); + prefs_tab_helper_.reset(new PrefsTabHelper(contents)); + prerender_tab_helper_.reset(new prerender::PrerenderTabHelper(this)); + restore_tab_helper_.reset(new RestoreTabHelper(contents)); + search_engine_tab_helper_.reset(new SearchEngineTabHelper(contents)); + snapshot_tab_helper_.reset(new SnapshotTabHelper(contents)); + ssl_helper_.reset(new TabContentsSSLHelper(this)); + synced_tab_delegate_.reset(new TabContentsWrapperSyncedTabDelegate(this)); + content_settings_.reset(new TabSpecificContentSettings(contents)); + translate_tab_helper_.reset(new TranslateTabHelper(contents)); + web_intent_picker_controller_.reset(new WebIntentPickerController(this)); + zoom_controller_.reset(new ZoomController(this)); + +#if !defined(OS_ANDROID) + print_view_manager_.reset(new printing::PrintViewManager(this)); + sad_tab_helper_.reset(new SadTabHelper(contents)); +#endif + + // Create the per-tab observers. + alternate_error_page_tab_observer_.reset( + new AlternateErrorPageTabObserver(contents, profile())); + webnavigation_observer_.reset( + new extensions::WebNavigationTabObserver(contents)); + external_protocol_observer_.reset(new ExternalProtocolObserver(contents)); + pdf_tab_observer_.reset(new PDFTabObserver(this)); + safe_browsing_tab_observer_.reset( + new safe_browsing::SafeBrowsingTabObserver(this)); + +#if defined(OS_WIN) + // Metro mode Chrome on Windows does not support plugins. Avoid registering + // the PluginObserver so we don't popup plugin-related infobars. + if (!base::win::GetMetroModule()) + plugin_observer_.reset(new PluginObserver(this)); +#else + plugin_observer_.reset(new PluginObserver(this)); +#endif + +#if !defined(OS_ANDROID) + if (OmniboxSearchHint::IsEnabled(profile())) + omnibox_search_hint_.reset(new OmniboxSearchHint(this)); + print_preview_.reset(new printing::PrintPreviewMessageHandler(contents)); +#endif + + // Start the in-browser thumbnailing if the feature is enabled. + if (ShouldEnableInBrowserThumbnailing()) { + thumbnail_generator_.reset(new ThumbnailGenerator); + thumbnail_generator_->StartThumbnailing(web_contents_.get()); + } + + // If this is not an incognito window, setup to handle one-click login. + // We don't want to check that the profile is already connected at this time + // because the connected state may change while this tab is open. Having a + // one-click signin helper attached does not cause problems if the profile + // happens to be already connected. +#if defined(ENABLE_ONE_CLICK_SIGNIN) + if (OneClickSigninHelper::CanOffer(contents, false)) + one_click_signin_helper_.reset(new OneClickSigninHelper(contents)); +#endif +} + +TabContents::~TabContents() { + in_destructor_ = true; + + // Need to reset |thumbnail_generator_| here before |web_contents_| is + // deleted because destructing |web_contents_| can end up causing the + // thumbnailer to generate a thumbnail. Since TabContents can be + // destructed during shutdown, trying to generate a thumbnail by sending an + // IPC message to the GPU process is not safe. Sending + // chrome::NOTIFICATION_TAB_CONTENTS_DESTROYED can also cause the thumbnailer + // to generate a thumbnail, so this must be placed before sending the + // notification. + thumbnail_generator_.reset(); + + content::NotificationService::current()->Notify( + chrome::NOTIFICATION_TAB_CONTENTS_DESTROYED, + content::Source<TabContents>(this), + content::NotificationService::NoDetails()); + + // Need to tear down infobars before the WebContents goes away. + // TODO(avi): Can we get this handled by the tab helper itself? + infobar_tab_helper_.reset(); +} + +base::PropertyAccessor<TabContents*>* TabContents::property_accessor() { + return g_tab_contents_wrapper_property_accessor.Pointer(); +} + +TabContents* TabContents::Clone() { + WebContents* new_contents = web_contents()->Clone(); + TabContents* new_wrapper = new TabContents(new_contents); + + // TODO(avi): Can we generalize this so that knowledge of the functionings of + // the tab helpers isn't required here? + new_wrapper->extension_tab_helper()->CopyStateFrom( + *extension_tab_helper_.get()); + return new_wrapper; +} + +// static +TabContents* TabContents::GetCurrentWrapperForContents( + WebContents* contents) { + TabContents** wrapper = + property_accessor()->GetProperty(contents->GetPropertyBag()); + + return wrapper ? *wrapper : NULL; +} + +// static +const TabContents* TabContents::GetCurrentWrapperForContents( + const WebContents* contents) { + TabContents* const* wrapper = + property_accessor()->GetProperty(contents->GetPropertyBag()); + + return wrapper ? *wrapper : NULL; +} + +WebContents* TabContents::web_contents() const { + return web_contents_.get(); +} + +Profile* TabContents::profile() const { + return Profile::FromBrowserContext(web_contents()->GetBrowserContext()); +} + +//////////////////////////////////////////////////////////////////////////////// +// WebContentsObserver overrides + +void TabContents::WebContentsDestroyed(WebContents* tab) { + // Destruction of the WebContents should only be done by us from our + // destructor. Otherwise it's very likely we (or one of the helpers we own) + // will attempt to access the WebContents and we'll crash. + DCHECK(in_destructor_); +} |