Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(266)

Side by Side Diff: chrome/browser/infobars/infobar_tab_helper.cc

Issue 14241006: Eliminate InfoBarTabHelper. Make InfoBarService a concrete class. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/infobars/infobar_tab_helper.h"
6
7 #include "chrome/browser/infobars/infobar.h"
8 #include "chrome/browser/infobars/infobar_delegate.h"
9 #include "chrome/browser/infobars/insecure_content_infobar_delegate.h"
10 #include "chrome/common/chrome_notification_types.h"
11 #include "chrome/common/render_messages.h"
12 #include "content/public/browser/navigation_controller.h"
13 #include "content/public/browser/notification_service.h"
14 #include "content/public/browser/web_contents.h"
15
16 using content::NavigationController;
17 using content::WebContents;
18
19 DEFINE_WEB_CONTENTS_USER_DATA_KEY(InfoBarTabHelper);
20
21 void InfoBarService::CreateForWebContents(content::WebContents* web_contents) {
22 return content::WebContentsUserData<InfoBarTabHelper>::CreateForWebContents(
23 web_contents);
24 }
25
26 InfoBarService* InfoBarService::FromWebContents(WebContents* web_contents) {
27 return content::WebContentsUserData<InfoBarTabHelper>::FromWebContents(
28 web_contents);
29 }
30
31 const InfoBarService* InfoBarService::FromWebContents(
32 const WebContents* web_contents) {
33 return content::WebContentsUserData<InfoBarTabHelper>::FromWebContents(
34 web_contents);
35 }
36
37 InfoBarService::~InfoBarService() {
38 }
39
40 InfoBarTabHelper::InfoBarTabHelper(WebContents* web_contents)
41 : content::WebContentsObserver(web_contents),
42 infobars_enabled_(true) {
43 DCHECK(web_contents);
44 registrar_.Add(this,
45 content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
46 content::Source<WebContents>(web_contents));
47 }
48
49 InfoBarTabHelper::~InfoBarTabHelper() {
50 // Destroy all remaining InfoBars. It's important to not animate here so that
51 // we guarantee that we'll delete all delegates before we do anything else.
52 //
53 // TODO(pkasting): If there is no InfoBarContainer, this leaks all the
54 // InfoBarDelegates. This will be fixed once we call CloseSoon() directly on
55 // Infobars.
56 RemoveAllInfoBars(false);
57 }
58
59 void InfoBarTabHelper::SetInfoBarsEnabled(bool enabled) {
60 infobars_enabled_ = enabled;
61 }
62
63 InfoBarDelegate* InfoBarTabHelper::AddInfoBar(
64 scoped_ptr<InfoBarDelegate> delegate) {
65 if (!infobars_enabled_)
66 return NULL;
67
68 for (InfoBars::const_iterator i(infobars_.begin()); i != infobars_.end();
69 ++i) {
70 if ((*i)->EqualsDelegate(delegate.get())) {
71 DCHECK_NE(*i, delegate.get());
72 return NULL;
73 }
74 }
75
76 // TODO(pkasting): Consider removing InfoBarTabHelper arg from delegate
77 // constructors and instead using a setter from here.
78 InfoBarDelegate* delegate_ptr = delegate.release();
79 infobars_.push_back(delegate_ptr);
80 // Add ourselves as an observer for navigations the first time a delegate is
81 // added. We use this notification to expire InfoBars that need to expire on
82 // page transitions.
83 if (infobars_.size() == 1) {
84 registrar_.Add(
85 this, content::NOTIFICATION_NAV_ENTRY_COMMITTED,
86 content::Source<NavigationController>(
87 &web_contents()->GetController()));
88 }
89
90 content::NotificationService::current()->Notify(
91 chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_ADDED,
92 content::Source<InfoBarService>(this),
93 content::Details<InfoBarAddedDetails>(delegate_ptr));
94 return delegate_ptr;
95 }
96
97 void InfoBarTabHelper::RemoveInfoBar(InfoBarDelegate* delegate) {
98 RemoveInfoBarInternal(delegate, true);
99 }
100
101 InfoBarDelegate* InfoBarTabHelper::ReplaceInfoBar(
102 InfoBarDelegate* old_delegate,
103 scoped_ptr<InfoBarDelegate> new_delegate) {
104 if (!infobars_enabled_)
105 return AddInfoBar(new_delegate.Pass()); // Deletes the delegate.
106
107 InfoBars::iterator i(std::find(infobars_.begin(), infobars_.end(),
108 old_delegate));
109 DCHECK(i != infobars_.end());
110
111 InfoBarDelegate* new_delegate_ptr = new_delegate.release();
112 i = infobars_.insert(i, new_delegate_ptr);
113 InfoBarReplacedDetails replaced_details(old_delegate, new_delegate_ptr);
114 // Remove the old delegate before notifying, so that if any observers call
115 // back to AddInfoBar() or similar, we don't dupe-check against this delegate.
116 infobars_.erase(++i);
117
118 old_delegate->clear_owner();
119 content::NotificationService::current()->Notify(
120 chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REPLACED,
121 content::Source<InfoBarService>(this),
122 content::Details<InfoBarReplacedDetails>(&replaced_details));
123 return new_delegate_ptr;
124 }
125
126 size_t InfoBarTabHelper::GetInfoBarCount() const {
127 return infobars_.size();
128 }
129
130 InfoBarDelegate* InfoBarTabHelper::GetInfoBarDelegateAt(size_t index) {
131 return infobars_[index];
132 }
133
134 content::WebContents* InfoBarTabHelper::GetWebContents() {
135 return content::WebContentsObserver::web_contents();
136 }
137
138 void InfoBarTabHelper::RenderViewGone(base::TerminationStatus status) {
139 RemoveAllInfoBars(true);
140 }
141
142 bool InfoBarTabHelper::OnMessageReceived(const IPC::Message& message) {
143 bool handled = true;
144 IPC_BEGIN_MESSAGE_MAP(InfoBarTabHelper, message)
145 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_DidBlockDisplayingInsecureContent,
146 OnDidBlockDisplayingInsecureContent)
147 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_DidBlockRunningInsecureContent,
148 OnDidBlockRunningInsecureContent)
149 IPC_MESSAGE_UNHANDLED(handled = false)
150 IPC_END_MESSAGE_MAP()
151 return handled;
152 }
153
154 void InfoBarTabHelper::Observe(int type,
155 const content::NotificationSource& source,
156 const content::NotificationDetails& details) {
157 if (type == content::NOTIFICATION_NAV_ENTRY_COMMITTED) {
158 DCHECK(&web_contents()->GetController() ==
159 content::Source<NavigationController>(source).ptr());
160
161 content::LoadCommittedDetails& committed_details =
162 *(content::Details<content::LoadCommittedDetails>(details).ptr());
163
164 // NOTE: It is not safe to change the following code to count upwards or
165 // use iterators, as the RemoveInfoBar() call synchronously modifies our
166 // delegate list.
167 for (size_t i = infobars_.size(); i > 0; --i) {
168 InfoBarDelegate* delegate = GetInfoBarDelegateAt(i - 1);
169 if (delegate->ShouldExpire(committed_details))
170 RemoveInfoBar(delegate);
171 }
172
173 return;
174 }
175
176 DCHECK_EQ(type, content::NOTIFICATION_WEB_CONTENTS_DESTROYED);
177 // The WebContents is going away; be aggressively paranoid and delete
178 // ourselves lest other parts of the system attempt to add infobars or use
179 // us otherwise during the destruction.
180 DCHECK_EQ(web_contents(), content::Source<WebContents>(source).ptr());
181 web_contents()->RemoveUserData(UserDataKey());
182 // That was the equivalent of "delete this". This object is now destroyed;
183 // returning from this function is the only safe thing to do.
184 return;
185 }
186 void InfoBarTabHelper::RemoveInfoBarInternal(InfoBarDelegate* delegate,
187 bool animate) {
188 if (!infobars_enabled_) {
189 DCHECK(infobars_.empty());
190 return;
191 }
192
193 InfoBars::iterator i(std::find(infobars_.begin(), infobars_.end(), delegate));
194 DCHECK(i != infobars_.end());
195
196 delegate->clear_owner();
197 // Remove the delegate before notifying, so that if any observers call back to
198 // AddInfoBar() or similar, we don't dupe-check against this delegate.
199 infobars_.erase(i);
200 // Remove ourselves as an observer if we are tracking no more InfoBars.
201 if (infobars_.empty()) {
202 registrar_.Remove(
203 this, content::NOTIFICATION_NAV_ENTRY_COMMITTED,
204 content::Source<NavigationController>(
205 &web_contents()->GetController()));
206 }
207
208 InfoBarRemovedDetails removed_details(delegate, animate);
209 content::NotificationService::current()->Notify(
210 chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED,
211 content::Source<InfoBarService>(this),
212 content::Details<InfoBarRemovedDetails>(&removed_details));
213 }
214
215 void InfoBarTabHelper::RemoveAllInfoBars(bool animate) {
216 while (!infobars_.empty())
217 RemoveInfoBarInternal(GetInfoBarDelegateAt(GetInfoBarCount() - 1), animate);
218 }
219
220 void InfoBarTabHelper::OnDidBlockDisplayingInsecureContent() {
221 InsecureContentInfoBarDelegate::Create(
222 this, InsecureContentInfoBarDelegate::DISPLAY);
223 }
224
225 void InfoBarTabHelper::OnDidBlockRunningInsecureContent() {
226 InsecureContentInfoBarDelegate::Create(this,
227 InsecureContentInfoBarDelegate::RUN);
228 }
OLDNEW
« no previous file with comments | « chrome/browser/infobars/infobar_tab_helper.h ('k') | chrome/browser/infobars/infobars_browsertest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698