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

Side by Side Diff: chrome/browser/infobars/infobar_service.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
Property Changes:
Added: svn:eol-style
## -0,0 +1 ##
+LF
\ No newline at end of property
OLDNEW
(Empty)
1 // Copyright (c) 2013 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_service.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
17 DEFINE_WEB_CONTENTS_USER_DATA_KEY(InfoBarService);
18
19 InfoBarDelegate* InfoBarService::AddInfoBar(
20 scoped_ptr<InfoBarDelegate> delegate) {
21 if (!infobars_enabled_)
22 return NULL;
23
24 for (InfoBars::const_iterator i(infobars_.begin()); i != infobars_.end();
25 ++i) {
26 if ((*i)->EqualsDelegate(delegate.get())) {
27 DCHECK_NE(*i, delegate.get());
28 return NULL;
29 }
30 }
31
32 // TODO(pkasting): Consider removing InfoBarService arg from delegate
33 // constructors and instead using a setter from here.
34 InfoBarDelegate* delegate_ptr = delegate.release();
35 infobars_.push_back(delegate_ptr);
36 // Add ourselves as an observer for navigations the first time a delegate is
37 // added. We use this notification to expire InfoBars that need to expire on
38 // page transitions.
39 if (infobars_.size() == 1) {
40 registrar_.Add(
41 this, content::NOTIFICATION_NAV_ENTRY_COMMITTED,
42 content::Source<content::NavigationController>(
43 &web_contents()->GetController()));
44 }
45
46 content::NotificationService::current()->Notify(
47 chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_ADDED,
48 content::Source<InfoBarService>(this),
49 content::Details<InfoBarAddedDetails>(delegate_ptr));
50 return delegate_ptr;
51 }
52
53 void InfoBarService::RemoveInfoBar(InfoBarDelegate* delegate) {
54 RemoveInfoBarInternal(delegate, true);
55 }
56
57 InfoBarDelegate* InfoBarService::ReplaceInfoBar(
58 InfoBarDelegate* old_delegate,
59 scoped_ptr<InfoBarDelegate> new_delegate) {
60 if (!infobars_enabled_)
61 return AddInfoBar(new_delegate.Pass()); // Deletes the delegate.
62
63 InfoBars::iterator i(std::find(infobars_.begin(), infobars_.end(),
64 old_delegate));
65 DCHECK(i != infobars_.end());
66
67 InfoBarDelegate* new_delegate_ptr = new_delegate.release();
68 i = infobars_.insert(i, new_delegate_ptr);
69 InfoBarReplacedDetails replaced_details(old_delegate, new_delegate_ptr);
70 // Remove the old delegate before notifying, so that if any observers call
71 // back to AddInfoBar() or similar, we don't dupe-check against this delegate.
72 infobars_.erase(++i);
73
74 old_delegate->clear_owner();
75 content::NotificationService::current()->Notify(
76 chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REPLACED,
77 content::Source<InfoBarService>(this),
78 content::Details<InfoBarReplacedDetails>(&replaced_details));
79 return new_delegate_ptr;
80 }
81
82 InfoBarService::InfoBarService(content::WebContents* web_contents)
83 : content::WebContentsObserver(web_contents),
84 infobars_enabled_(true) {
85 DCHECK(web_contents);
86 registrar_.Add(this,
87 content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
88 content::Source<content::WebContents>(web_contents));
89 }
90
91 InfoBarService::~InfoBarService() {
92 // Destroy all remaining InfoBars. It's important to not animate here so that
93 // we guarantee that we'll delete all delegates before we do anything else.
94 //
95 // TODO(pkasting): If there is no InfoBarContainer, this leaks all the
96 // InfoBarDelegates. This will be fixed once we call CloseSoon() directly on
97 // Infobars.
98 RemoveAllInfoBars(false);
99 }
100
101 void InfoBarService::RenderViewGone(base::TerminationStatus status) {
102 RemoveAllInfoBars(true);
103 }
104
105 bool InfoBarService::OnMessageReceived(const IPC::Message& message) {
106 bool handled = true;
107 IPC_BEGIN_MESSAGE_MAP(InfoBarService, message)
108 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_DidBlockDisplayingInsecureContent,
109 OnDidBlockDisplayingInsecureContent)
110 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_DidBlockRunningInsecureContent,
111 OnDidBlockRunningInsecureContent)
112 IPC_MESSAGE_UNHANDLED(handled = false)
113 IPC_END_MESSAGE_MAP()
114 return handled;
115 }
116
117 void InfoBarService::Observe(int type,
118 const content::NotificationSource& source,
119 const content::NotificationDetails& details) {
120 if (type == content::NOTIFICATION_NAV_ENTRY_COMMITTED) {
121 DCHECK(&web_contents()->GetController() ==
122 content::Source<content::NavigationController>(source).ptr());
123
124 content::LoadCommittedDetails& committed_details =
125 *(content::Details<content::LoadCommittedDetails>(details).ptr());
126
127 // NOTE: It is not safe to change the following code to count upwards or
128 // use iterators, as the RemoveInfoBar() call synchronously modifies our
129 // delegate list.
130 for (size_t i = infobars_.size(); i > 0; --i) {
131 InfoBarDelegate* delegate = infobars_[i - 1];
132 if (delegate->ShouldExpire(committed_details))
133 RemoveInfoBar(delegate);
134 }
135
136 return;
137 }
138
139 DCHECK_EQ(type, content::NOTIFICATION_WEB_CONTENTS_DESTROYED);
140 // The WebContents is going away; be aggressively paranoid and delete
141 // ourselves lest other parts of the system attempt to add infobars or use
142 // us otherwise during the destruction.
143 DCHECK_EQ(web_contents(),
144 content::Source<content::WebContents>(source).ptr());
145 web_contents()->RemoveUserData(UserDataKey());
146 // That was the equivalent of "delete this". This object is now destroyed;
147 // returning from this function is the only safe thing to do.
148 return;
149 }
150
151 void InfoBarService::RemoveInfoBarInternal(InfoBarDelegate* delegate,
152 bool animate) {
153 if (!infobars_enabled_) {
154 DCHECK(infobars_.empty());
155 return;
156 }
157
158 InfoBars::iterator i(std::find(infobars_.begin(), infobars_.end(), delegate));
159 DCHECK(i != infobars_.end());
160
161 delegate->clear_owner();
162 // Remove the delegate before notifying, so that if any observers call back to
163 // AddInfoBar() or similar, we don't dupe-check against this delegate.
164 infobars_.erase(i);
165 // Remove ourselves as an observer if we are tracking no more InfoBars.
166 if (infobars_.empty()) {
167 registrar_.Remove(
168 this, content::NOTIFICATION_NAV_ENTRY_COMMITTED,
169 content::Source<content::NavigationController>(
170 &web_contents()->GetController()));
171 }
172
173 InfoBarRemovedDetails removed_details(delegate, animate);
174 content::NotificationService::current()->Notify(
175 chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED,
176 content::Source<InfoBarService>(this),
177 content::Details<InfoBarRemovedDetails>(&removed_details));
178 }
179
180 void InfoBarService::RemoveAllInfoBars(bool animate) {
181 while (!infobars_.empty())
182 RemoveInfoBarInternal(infobars_.back(), animate);
183 }
184
185 void InfoBarService::OnDidBlockDisplayingInsecureContent() {
186 InsecureContentInfoBarDelegate::Create(
187 this, InsecureContentInfoBarDelegate::DISPLAY);
188 }
189
190 void InfoBarService::OnDidBlockRunningInsecureContent() {
191 InsecureContentInfoBarDelegate::Create(this,
192 InsecureContentInfoBarDelegate::RUN);
193 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698