diff options
author | thakis@chromium.org <thakis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-09-01 16:48:17 +0000 |
---|---|---|
committer | thakis@chromium.org <thakis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-09-01 16:48:17 +0000 |
commit | aa1834c788f85aef89c3e39cf8258e8d2ad42281 (patch) | |
tree | b26d28cfc982f0069fee45d4d8df4e60e519872e /chrome/browser/ui/tab_contents | |
parent | 25af8b0f78aa52c2484e71ae3c8ce36cf1a72051 (diff) | |
download | chromium_src-aa1834c788f85aef89c3e39cf8258e8d2ad42281.zip chromium_src-aa1834c788f85aef89c3e39cf8258e8d2ad42281.tar.gz chromium_src-aa1834c788f85aef89c3e39cf8258e8d2ad42281.tar.bz2 |
Revert 99187 (speculative revert for ProfileSyncServiceSessionTest.FailModelAssociation on 10.5)
- Move infobar handling to a tab helper, part 1.
BUG=94741
TEST=no visible change
Review URL: http://codereview.chromium.org/7810002
TBR=avi@chromium.org
Review URL: http://codereview.chromium.org/7827017
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@99198 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/ui/tab_contents')
-rw-r--r-- | chrome/browser/ui/tab_contents/tab_contents_wrapper.cc | 174 | ||||
-rw-r--r-- | chrome/browser/ui/tab_contents/tab_contents_wrapper.h | 50 |
2 files changed, 213 insertions, 11 deletions
diff --git a/chrome/browser/ui/tab_contents/tab_contents_wrapper.cc b/chrome/browser/ui/tab_contents/tab_contents_wrapper.cc index 4f68103..4c42de2 100644 --- a/chrome/browser/ui/tab_contents/tab_contents_wrapper.cc +++ b/chrome/browser/ui/tab_contents/tab_contents_wrapper.cc @@ -6,8 +6,9 @@ #include "base/utf_string_conversions.h" +#include "base/command_line.h" #include "base/lazy_instance.h" -#include "base/stringprintf.h" +#include "base/utf_string_conversions.h" #include "chrome/browser/autocomplete_history_manager.h" #include "chrome/browser/autofill/autofill_manager.h" #include "chrome/browser/automation/automation_tab_helper.h" @@ -19,9 +20,10 @@ #include "chrome/browser/extensions/extension_webnavigation_api.h" #include "chrome/browser/external_protocol/external_protocol_observer.h" #include "chrome/browser/favicon/favicon_tab_helper.h" +#include "chrome/browser/file_select_helper.h" #include "chrome/browser/google/google_util.h" #include "chrome/browser/history/history_tab_helper.h" -#include "chrome/browser/infobars/infobar_tab_helper.h" +#include "chrome/browser/intents/web_intent_data.h" #include "chrome/browser/omnibox_search_hint.h" #include "chrome/browser/password_manager/password_manager.h" #include "chrome/browser/password_manager_delegate_impl.h" @@ -31,11 +33,17 @@ #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/profiles/profile.h" #include "chrome/browser/remoting/firewall_traversal_observer.h" #include "chrome/browser/renderer_host/web_cache_manager.h" #include "chrome/browser/renderer_preferences_util.h" #include "chrome/browser/sessions/restore_tab_helper.h" #include "chrome/browser/safe_browsing/client_side_detection_host.h" +#include "chrome/browser/sync/glue/synced_tab_delegate.h" +#include "chrome/browser/tab_contents/infobar.h" +#include "chrome/browser/tab_contents/infobar_delegate.h" +#include "chrome/browser/tab_contents/insecure_content_infobar_delegate.h" +#include "chrome/browser/tab_contents/simple_alert_infobar_delegate.h" #include "chrome/browser/tab_contents/tab_contents_ssl_helper.h" #include "chrome/browser/tab_contents/thumbnail_generator.h" #include "chrome/browser/themes/theme_service.h" @@ -52,8 +60,12 @@ #include "chrome/common/chrome_switches.h" #include "chrome/common/pref_names.h" #include "chrome/common/render_messages.h" +#include "content/browser/child_process_security_policy.h" #include "content/browser/renderer_host/render_view_host.h" +#include "content/browser/tab_contents/navigation_details.h" +#include "content/browser/tab_contents/tab_contents.h" #include "content/browser/tab_contents/tab_contents_view.h" +#include "content/browser/user_metrics.h" #include "content/common/notification_service.h" #include "content/common/view_messages.h" #include "grit/generated_resources.h" @@ -200,6 +212,7 @@ const size_t kPerScriptFontDefaultsLength = arraysize(kPerScriptFontDefaults); TabContentsWrapper::TabContentsWrapper(TabContents* contents) : TabContentsObserver(contents), delegate_(NULL), + infobars_enabled_(true), ALLOW_THIS_IN_INITIALIZER_LIST( synced_tab_delegate_(new TabContentsWrapperSyncedTabDelegate(this))), in_destructor_(false), @@ -220,7 +233,6 @@ TabContentsWrapper::TabContentsWrapper(TabContents* contents) favicon_tab_helper_.reset(new FaviconTabHelper(contents)); find_tab_helper_.reset(new FindTabHelper(contents)); history_tab_helper_.reset(new HistoryTabHelper(contents)); - infobar_tab_helper_.reset(new InfoBarTabHelper(this)); password_manager_delegate_.reset(new PasswordManagerDelegateImpl(this)); password_manager_.reset( new PasswordManager(contents, password_manager_delegate_.get())); @@ -286,8 +298,13 @@ TabContentsWrapper::TabContentsWrapper(TabContents* contents) TabContentsWrapper::~TabContentsWrapper() { in_destructor_ = true; - // Need to tear down infobars before the TabContents goes away. - infobar_tab_helper_.reset(); + // Destroy all remaining InfoBars. It's important to not animate here so that + // we guarantee that we'll delete all delegates before we do anything else. + // + // TODO(pkasting): If there is no InfoBarContainer, this leaks all the + // InfoBarDelegates. This will be fixed once we call CloseSoon() directly on + // Infobars. + RemoveAllInfoBars(false); } PropertyAccessor<TabContentsWrapper*>* TabContentsWrapper::property_accessor() { @@ -504,6 +521,8 @@ void TabContentsWrapper::RenderViewCreated(RenderViewHost* render_view_host) { } void TabContentsWrapper::RenderViewGone() { + RemoveAllInfoBars(true); + // Tell the view that we've crashed so it can prepare the sad tab page. // Only do this if we're not in browser shutdown, so that TabContents // objects that are not in a browser (e.g., HTML dialogs) and thus are @@ -525,6 +544,10 @@ bool TabContentsWrapper::OnMessageReceived(const IPC::Message& message) { IPC_MESSAGE_HANDLER(ChromeViewHostMsg_Snapshot, OnSnapshot) IPC_MESSAGE_HANDLER(ChromeViewHostMsg_PDFHasUnsupportedFeature, OnPDFHasUnsupportedFeature) + IPC_MESSAGE_HANDLER(ChromeViewHostMsg_DidBlockDisplayingInsecureContent, + OnDidBlockDisplayingInsecureContent) + IPC_MESSAGE_HANDLER(ChromeViewHostMsg_DidBlockRunningInsecureContent, + OnDidBlockRunningInsecureContent) IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP() return handled; @@ -541,6 +564,24 @@ void TabContentsWrapper::Observe(int type, const NotificationSource& source, const NotificationDetails& details) { switch (type) { + case content::NOTIFICATION_NAV_ENTRY_COMMITTED: { + DCHECK(&tab_contents_->controller() == + Source<NavigationController>(source).ptr()); + + content::LoadCommittedDetails& committed_details = + *(Details<content::LoadCommittedDetails>(details).ptr()); + + // NOTE: It is not safe to change the following code to count upwards or + // use iterators, as the RemoveInfoBar() call synchronously modifies our + // delegate list. + for (size_t i = infobars_.size(); i > 0; --i) { + InfoBarDelegate* delegate = GetInfoBarDelegateAt(i - 1); + if (delegate->ShouldExpire(committed_details)) + RemoveInfoBar(delegate); + } + + break; + } case chrome::NOTIFICATION_GOOGLE_URL_UPDATED: UpdateAlternateErrorPageURL(render_view_host()); break; @@ -578,6 +619,67 @@ void TabContentsWrapper::Observe(int type, } } +void TabContentsWrapper::AddInfoBar(InfoBarDelegate* delegate) { + if (!infobars_enabled_) { + delegate->InfoBarClosed(); + return; + } + + for (size_t i = 0; i < infobars_.size(); ++i) { + if (GetInfoBarDelegateAt(i)->EqualsDelegate(delegate)) { + delegate->InfoBarClosed(); + return; + } + } + + infobars_.push_back(delegate); + NotificationService::current()->Notify( + chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_ADDED, + Source<TabContentsWrapper>(this), Details<InfoBarAddedDetails>(delegate)); + + // Add ourselves as an observer for navigations the first time a delegate is + // added. We use this notification to expire InfoBars that need to expire on + // page transitions. + if (infobars_.size() == 1) { + registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED, + Source<NavigationController>(&tab_contents_->controller())); + } +} + +void TabContentsWrapper::RemoveInfoBar(InfoBarDelegate* delegate) { + RemoveInfoBarInternal(delegate, true); +} + +void TabContentsWrapper::ReplaceInfoBar(InfoBarDelegate* old_delegate, + InfoBarDelegate* new_delegate) { + if (!infobars_enabled_) { + AddInfoBar(new_delegate); // Deletes the delegate. + return; + } + + size_t i; + for (i = 0; i < infobars_.size(); ++i) { + if (GetInfoBarDelegateAt(i) == old_delegate) + break; + } + DCHECK_LT(i, infobars_.size()); + + infobars_.insert(infobars_.begin() + i, new_delegate); + + old_delegate->clear_owner(); + InfoBarReplacedDetails replaced_details(old_delegate, new_delegate); + NotificationService::current()->Notify( + chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REPLACED, + Source<TabContentsWrapper>(this), + Details<InfoBarReplacedDetails>(&replaced_details)); + + infobars_.erase(infobars_.begin() + i + 1); +} + +InfoBarDelegate* TabContentsWrapper::GetInfoBarDelegateAt(size_t index) { + return infobars_[index]; +} + //////////////////////////////////////////////////////////////////////////////// // Internal helpers @@ -592,6 +694,33 @@ void TabContentsWrapper::OnPDFHasUnsupportedFeature() { PDFHasUnsupportedFeature(this); } +void TabContentsWrapper::OnDidBlockDisplayingInsecureContent() { + // At most one infobar and do not supersede the stronger running content bar. + for (size_t i = 0; i < infobars_.size(); ++i) { + if (GetInfoBarDelegateAt(i)->AsInsecureContentInfoBarDelegate()) + return; + } + AddInfoBar(new InsecureContentInfoBarDelegate(this, + InsecureContentInfoBarDelegate::DISPLAY)); +} + +void TabContentsWrapper::OnDidBlockRunningInsecureContent() { + // At most one infobar superseding any weaker displaying content bar. + for (size_t i = 0; i < infobars_.size(); ++i) { + InsecureContentInfoBarDelegate* delegate = + GetInfoBarDelegateAt(i)->AsInsecureContentInfoBarDelegate(); + if (delegate) { + if (delegate->type() != InsecureContentInfoBarDelegate::RUN) { + ReplaceInfoBar(delegate, new InsecureContentInfoBarDelegate(this, + InsecureContentInfoBarDelegate::RUN)); + } + return; + } + } + AddInfoBar(new InsecureContentInfoBarDelegate(this, + InsecureContentInfoBarDelegate::RUN)); +} + GURL TabContentsWrapper::GetAlternateErrorPageURL() const { GURL url; // Disable alternate error pages when in Incognito mode. @@ -642,6 +771,41 @@ void TabContentsWrapper::UpdateSafebrowsingDetectionHost() { #endif } +void TabContentsWrapper::RemoveInfoBarInternal(InfoBarDelegate* delegate, + bool animate) { + if (!infobars_enabled_) { + DCHECK(infobars_.empty()); + return; + } + + size_t i; + for (i = 0; i < infobars_.size(); ++i) { + if (GetInfoBarDelegateAt(i) == delegate) + break; + } + DCHECK_LT(i, infobars_.size()); + InfoBarDelegate* infobar = infobars_[i]; + + infobar->clear_owner(); + InfoBarRemovedDetails removed_details(infobar, animate); + NotificationService::current()->Notify( + chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED, + Source<TabContentsWrapper>(this), + Details<InfoBarRemovedDetails>(&removed_details)); + + infobars_.erase(infobars_.begin() + i); + // Remove ourselves as an observer if we are tracking no more InfoBars. + if (infobars_.empty()) { + registrar_.Remove(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED, + Source<NavigationController>(&tab_contents_->controller())); + } +} + +void TabContentsWrapper::RemoveAllInfoBars(bool animate) { + while (!infobars_.empty()) + RemoveInfoBarInternal(GetInfoBarDelegateAt(infobar_count() - 1), animate); +} + void TabContentsWrapper::ExitFullscreenMode() { Send(new ViewMsg_ExitFullscreen(routing_id())); } diff --git a/chrome/browser/ui/tab_contents/tab_contents_wrapper.h b/chrome/browser/ui/tab_contents/tab_contents_wrapper.h index 019c0b7..4eec779 100644 --- a/chrome/browser/ui/tab_contents/tab_contents_wrapper.h +++ b/chrome/browser/ui/tab_contents/tab_contents_wrapper.h @@ -32,7 +32,7 @@ class FaviconTabHelper; class FileSelectObserver; class FindTabHelper; class FirewallTraversalObserver; -class InfoBarTabHelper; +class InfoBarDelegate; class HistoryTabHelper; class NavigationController; class OmniboxSearchHint; @@ -104,9 +104,6 @@ class TabContentsWrapper : public TabContentsObserver, // Captures a snapshot of the page. void CaptureSnapshot(); - // Stop this tab rendering in fullscreen mode. - void ExitFullscreenMode(); - // Helper to retrieve the existing instance that wraps a given TabContents. // Returns NULL if there is no such existing instance. // NOTE: This is not intended for general use. It is intended for situations @@ -169,7 +166,6 @@ class TabContentsWrapper : public TabContentsObserver, FaviconTabHelper* favicon_tab_helper() { return favicon_tab_helper_.get(); } FindTabHelper* find_tab_helper() { return find_tab_helper_.get(); } HistoryTabHelper* history_tab_helper() { return history_tab_helper_.get(); } - InfoBarTabHelper* infobar_tab_helper() { return infobar_tab_helper_.get(); } PasswordManager* password_manager() { return password_manager_.get(); } prerender::PrerenderTabHelper* prerender_tab_helper() { @@ -224,12 +220,48 @@ class TabContentsWrapper : public TabContentsObserver, const NotificationSource& source, const NotificationDetails& details) OVERRIDE; + // Infobars ------------------------------------------------------------------ + + // Adds an InfoBar for the specified |delegate|. + // + // If infobars are disabled for this tab or the tab already has a delegate + // which returns true for InfoBarDelegate::EqualsDelegate(delegate), + // |delegate| is closed immediately without being added. + void AddInfoBar(InfoBarDelegate* delegate); + + // Removes the InfoBar for the specified |delegate|. + // + // If infobars are disabled for this tab, this will do nothing, on the + // assumption that the matching AddInfoBar() call will have already closed the + // delegate (see above). + void RemoveInfoBar(InfoBarDelegate* delegate); + + // Replaces one infobar with another, without any animation in between. + // + // If infobars are disabled for this tab, |new_delegate| is closed immediately + // without being added, and nothing else happens. + // + // NOTE: This does not perform any EqualsDelegate() checks like AddInfoBar(). + void ReplaceInfoBar(InfoBarDelegate* old_delegate, + InfoBarDelegate* new_delegate); + + // Enumeration and access functions. + size_t infobar_count() const { return infobars_.size(); } + // WARNING: This does not sanity-check |index|! + InfoBarDelegate* GetInfoBarDelegateAt(size_t index); + void set_infobars_enabled(bool value) { infobars_enabled_ = value; } + + // Stop this tab rendering in fullscreen mode. + void ExitFullscreenMode(); + private: // Internal helpers ---------------------------------------------------------- // Message handlers. void OnSnapshot(const SkBitmap& bitmap); void OnPDFHasUnsupportedFeature(); + void OnDidBlockDisplayingInsecureContent(); + void OnDidBlockRunningInsecureContent(); // Returns the server that can provide alternate error pages. If the returned // URL is empty, the default error page built into WebKit will be used. @@ -248,11 +280,18 @@ class TabContentsWrapper : public TabContentsObserver, // safe browsing preference has changed. void UpdateSafebrowsingDetectionHost(); + void RemoveInfoBarInternal(InfoBarDelegate* delegate, bool animate); + void RemoveAllInfoBars(bool animate); + // Data for core operation --------------------------------------------------- // Delegate for notifying our owner about stuff. Not owned by us. TabContentsWrapperDelegate* delegate_; + // Delegates for InfoBars associated with this TabContentsWrapper. + std::vector<InfoBarDelegate*> infobars_; + bool infobars_enabled_; + NotificationRegistrar registrar_; PrefChangeRegistrar pref_change_registrar_; @@ -278,7 +317,6 @@ class TabContentsWrapper : public TabContentsObserver, scoped_ptr<FaviconTabHelper> favicon_tab_helper_; scoped_ptr<FindTabHelper> find_tab_helper_; scoped_ptr<HistoryTabHelper> history_tab_helper_; - scoped_ptr<InfoBarTabHelper> infobar_tab_helper_; // PasswordManager and its delegate. The delegate must outlive the manager, // per documentation in password_manager.h. |