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

Side by Side Diff: chrome/browser/content_settings/permission_queue_controller.cc

Issue 107413006: Dismiss EME infobar when WebMediaPlayer is destroyed. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: make FakeProfile class happy Created 6 years, 11 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
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/content_settings/permission_queue_controller.h" 5 #include "chrome/browser/content_settings/permission_queue_controller.h"
6 6
7 #include "base/prefs/pref_service.h" 7 #include "base/prefs/pref_service.h"
8 #include "chrome/browser/chrome_notification_types.h" 8 #include "chrome/browser/chrome_notification_types.h"
9 #include "chrome/browser/content_settings/host_content_settings_map.h" 9 #include "chrome/browser/content_settings/host_content_settings_map.h"
10 #include "chrome/browser/geolocation/geolocation_infobar_delegate.h" 10 #include "chrome/browser/geolocation/geolocation_infobar_delegate.h"
(...skipping 18 matching lines...) Expand all
29 29
30 InfoBarService* GetInfoBarService(const PermissionRequestID& id) { 30 InfoBarService* GetInfoBarService(const PermissionRequestID& id) {
31 content::WebContents* web_contents = 31 content::WebContents* web_contents =
32 tab_util::GetWebContentsByID(id.render_process_id(), id.render_view_id()); 32 tab_util::GetWebContentsByID(id.render_process_id(), id.render_view_id());
33 return web_contents ? InfoBarService::FromWebContents(web_contents) : NULL; 33 return web_contents ? InfoBarService::FromWebContents(web_contents) : NULL;
34 } 34 }
35 35
36 } 36 }
37 37
38 38
39 class PermissionQueueController::PendingInfoBarRequest { 39 class PermissionQueueController::PendingInfobarRequest {
40 public: 40 public:
41 PendingInfoBarRequest(ContentSettingsType type, 41 PendingInfobarRequest(ContentSettingsType type,
42 const PermissionRequestID& id, 42 const PermissionRequestID& id,
43 const GURL& requesting_frame, 43 const GURL& requesting_frame,
44 const GURL& embedder, 44 const GURL& embedder,
45 PermissionDecidedCallback callback); 45 PermissionDecidedCallback callback);
46 ~PendingInfoBarRequest(); 46 ~PendingInfobarRequest();
47 47
48 bool IsForPair(const GURL& requesting_frame, 48 bool IsForPair(const GURL& requesting_frame,
49 const GURL& embedder) const; 49 const GURL& embedder) const;
50 50
51 const PermissionRequestID& id() const { return id_; } 51 const PermissionRequestID& id() const { return id_; }
52 const GURL& requesting_frame() const { return requesting_frame_; } 52 const GURL& requesting_frame() const { return requesting_frame_; }
53 bool has_infobar() const { return !!infobar_; } 53 bool has_infobar() const { return !!infobar_; }
54 InfoBar* infobar() { return infobar_; } 54 InfoBar* infobar() { return infobar_; }
55 55
56 void RunCallback(bool allowed); 56 void RunCallback(bool allowed);
57 void CreateInfoBar(PermissionQueueController* controller, 57 void CreateInfoBar(PermissionQueueController* controller,
58 const std::string& display_languages); 58 const std::string& display_languages);
59 59
60 private: 60 private:
61 ContentSettingsType type_; 61 ContentSettingsType type_;
62 PermissionRequestID id_; 62 PermissionRequestID id_;
63 GURL requesting_frame_; 63 GURL requesting_frame_;
64 GURL embedder_; 64 GURL embedder_;
65 PermissionDecidedCallback callback_; 65 PermissionDecidedCallback callback_;
66 InfoBar* infobar_; 66 InfoBar* infobar_;
67 67
68 // Purposefully do not disable copying, as this is stored in STL containers. 68 // Purposefully do not disable copying, as this is stored in STL containers.
69 }; 69 };
70 70
71 PermissionQueueController::PendingInfoBarRequest::PendingInfoBarRequest( 71 PermissionQueueController::PendingInfobarRequest::PendingInfobarRequest(
72 ContentSettingsType type, 72 ContentSettingsType type,
73 const PermissionRequestID& id, 73 const PermissionRequestID& id,
74 const GURL& requesting_frame, 74 const GURL& requesting_frame,
75 const GURL& embedder, 75 const GURL& embedder,
76 PermissionDecidedCallback callback) 76 PermissionDecidedCallback callback)
77 : type_(type), 77 : type_(type),
78 id_(id), 78 id_(id),
79 requesting_frame_(requesting_frame), 79 requesting_frame_(requesting_frame),
80 embedder_(embedder), 80 embedder_(embedder),
81 callback_(callback), 81 callback_(callback),
82 infobar_(NULL) { 82 infobar_(NULL) {
83 } 83 }
84 84
85 PermissionQueueController::PendingInfoBarRequest::~PendingInfoBarRequest() { 85 PermissionQueueController::PendingInfobarRequest::~PendingInfobarRequest() {
86 } 86 }
87 87
88 bool PermissionQueueController::PendingInfoBarRequest::IsForPair( 88 bool PermissionQueueController::PendingInfobarRequest::IsForPair(
89 const GURL& requesting_frame, 89 const GURL& requesting_frame,
90 const GURL& embedder) const { 90 const GURL& embedder) const {
91 return (requesting_frame_ == requesting_frame) && (embedder_ == embedder); 91 return (requesting_frame_ == requesting_frame) && (embedder_ == embedder);
92 } 92 }
93 93
94 void PermissionQueueController::PendingInfoBarRequest::RunCallback( 94 void PermissionQueueController::PendingInfobarRequest::RunCallback(
95 bool allowed) { 95 bool allowed) {
96 callback_.Run(allowed); 96 callback_.Run(allowed);
97 } 97 }
98 98
99 void PermissionQueueController::PendingInfoBarRequest::CreateInfoBar( 99 void PermissionQueueController::PendingInfobarRequest::CreateInfoBar(
100 PermissionQueueController* controller, 100 PermissionQueueController* controller,
101 const std::string& display_languages) { 101 const std::string& display_languages) {
102 // TODO(toyoshim): Remove following ContentType dependent code. 102 // TODO(toyoshim): Remove following ContentType dependent code.
103 // Also these InfoBarDelegate can share much more code each other. 103 // Also these InfoBarDelegate can share much more code each other.
104 // http://crbug.com/266743 104 // http://crbug.com/266743
105 switch (type_) { 105 switch (type_) {
106 case CONTENT_SETTINGS_TYPE_GEOLOCATION: 106 case CONTENT_SETTINGS_TYPE_GEOLOCATION:
107 infobar_ = GeolocationInfoBarDelegate::Create( 107 infobar_ = GeolocationInfoBarDelegate::Create(
108 GetInfoBarService(id_), controller, id_, requesting_frame_, 108 GetInfoBarService(id_), controller, id_, requesting_frame_,
109 display_languages); 109 display_languages);
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
142 } 142 }
143 143
144 void PermissionQueueController::CreateInfoBarRequest( 144 void PermissionQueueController::CreateInfoBarRequest(
145 const PermissionRequestID& id, 145 const PermissionRequestID& id,
146 const GURL& requesting_frame, 146 const GURL& requesting_frame,
147 const GURL& embedder, 147 const GURL& embedder,
148 PermissionDecidedCallback callback) { 148 PermissionDecidedCallback callback) {
149 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 149 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
150 150
151 // We shouldn't get duplicate requests. 151 // We shouldn't get duplicate requests.
152 for (PendingInfoBarRequests::const_iterator i( 152 for (PendingInfobarRequests::const_iterator i(
153 pending_infobar_requests_.begin()); 153 pending_infobar_requests_.begin());
154 i != pending_infobar_requests_.end(); ++i) 154 i != pending_infobar_requests_.end(); ++i)
155 DCHECK(!i->id().Equals(id)); 155 DCHECK(!i->id().Equals(id));
156 156
157 pending_infobar_requests_.push_back(PendingInfoBarRequest( 157 pending_infobar_requests_.push_back(PendingInfobarRequest(
158 type_, id, requesting_frame, embedder, callback)); 158 type_, id, requesting_frame, embedder, callback));
159 if (!AlreadyShowingInfoBarForTab(id)) 159 if (!AlreadyShowingInfoBarForTab(id))
160 ShowQueuedInfoBarForTab(id); 160 ShowQueuedInfoBarForTab(id);
161 } 161 }
162 162
163 void PermissionQueueController::CancelInfoBarRequest( 163 void PermissionQueueController::CancelInfoBarRequest(
164 const PermissionRequestID& id) { 164 const PermissionRequestID& id) {
165 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 165 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
166 166
167 for (PendingInfoBarRequests::iterator i(pending_infobar_requests_.begin()); 167 for (PendingInfobarRequests::iterator i(pending_infobar_requests_.begin());
168 i != pending_infobar_requests_.end(); ++i) { 168 i != pending_infobar_requests_.end(); ++i) {
169 if (i->id().Equals(id)) { 169 if (i->id().Equals(id)) {
170 if (i->has_infobar()) 170 if (i->has_infobar())
171 GetInfoBarService(id)->RemoveInfoBar(i->infobar()); 171 GetInfoBarService(id)->RemoveInfoBar(i->infobar());
172 else 172 else
173 pending_infobar_requests_.erase(i); 173 pending_infobar_requests_.erase(i);
174 return; 174 return;
175 } 175 }
176 } 176 }
177 } 177 }
178 178
179 void PermissionQueueController::CancelInfoBarRequests(int group_id) {
180 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
181
182 // If we remove an infobar in the following loop, the next pending infobar
183 // will be shown. Therefore, we erase all the pending infobars first and
184 // remove an infobar later.
185 PendingInfobarRequests infobar_requests_to_cancel;
186 for (PendingInfobarRequests::iterator i = pending_infobar_requests_.begin();
187 i != pending_infobar_requests_.end();) {
188 if (i->id().group_id() == group_id) {
189 if (i->has_infobar()) {
190 // |i| will be erased from |pending_infobar_requests_|
191 // in |PermissionQueueController::Observe| when the infobar is removed.
192 infobar_requests_to_cancel.push_back(*i);
193 ++i;
194 } else {
195 i = pending_infobar_requests_.erase(i);
196 }
197 } else {
198 ++i;
199 }
200 }
201
202 for (PendingInfobarRequests::iterator i = infobar_requests_to_cancel.begin();
203 i != infobar_requests_to_cancel.end();
204 ++i) {
205 GetInfoBarService(i->id())->RemoveInfoBar(i->infobar());
206 }
207 }
208
179 void PermissionQueueController::OnPermissionSet( 209 void PermissionQueueController::OnPermissionSet(
180 const PermissionRequestID& id, 210 const PermissionRequestID& id,
181 const GURL& requesting_frame, 211 const GURL& requesting_frame,
182 const GURL& embedder, 212 const GURL& embedder,
183 bool update_content_setting, 213 bool update_content_setting,
184 bool allowed) { 214 bool allowed) {
185 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 215 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
186 216
187 if (update_content_setting) 217 if (update_content_setting)
188 UpdateContentSetting(requesting_frame, embedder, allowed); 218 UpdateContentSetting(requesting_frame, embedder, allowed);
189 219
190 // Cancel this request first, then notify listeners. TODO(pkasting): Why 220 // Cancel this request first, then notify listeners. TODO(pkasting): Why
191 // is this order important? 221 // is this order important?
192 PendingInfoBarRequests requests_to_notify; 222 PendingInfobarRequests requests_to_notify;
193 PendingInfoBarRequests infobars_to_remove; 223 PendingInfobarRequests infobars_to_remove;
194 for (PendingInfoBarRequests::iterator i = pending_infobar_requests_.begin(); 224 for (PendingInfobarRequests::iterator i = pending_infobar_requests_.begin();
195 i != pending_infobar_requests_.end(); ) { 225 i != pending_infobar_requests_.end(); ) {
196 if (i->IsForPair(requesting_frame, embedder)) { 226 if (i->IsForPair(requesting_frame, embedder)) {
197 requests_to_notify.push_back(*i); 227 requests_to_notify.push_back(*i);
198 if (i->id().Equals(id)) { 228 if (i->id().Equals(id)) {
199 // The infobar that called us is i->infobar(), and its delegate is 229 // The infobar that called us is i->infobar(), and its delegate is
200 // currently in either Accept() or Cancel(). This means that 230 // currently in either Accept() or Cancel(). This means that
201 // RemoveInfoBar() will be called later on, and that will trigger a 231 // RemoveInfoBar() will be called later on, and that will trigger a
202 // notification we're observing. 232 // notification we're observing.
203 ++i; 233 ++i;
204 } else if (i->has_infobar()) { 234 } else if (i->has_infobar()) {
205 // This infobar is for the same frame/embedder pair, but in a different 235 // This infobar is for the same frame/embedder pair, but in a different
206 // tab. We should remove it now that we've got an answer for it. 236 // tab. We should remove it now that we've got an answer for it.
207 infobars_to_remove.push_back(*i); 237 infobars_to_remove.push_back(*i);
208 ++i; 238 ++i;
209 } else { 239 } else {
210 // We haven't created an infobar yet, just remove the pending request. 240 // We haven't created an infobar yet, just remove the pending request.
211 i = pending_infobar_requests_.erase(i); 241 i = pending_infobar_requests_.erase(i);
212 } 242 }
213 } else { 243 } else {
214 ++i; 244 ++i;
215 } 245 }
216 } 246 }
217 247
218 // Remove all infobars for the same |requesting_frame| and |embedder|. 248 // Remove all infobars for the same |requesting_frame| and |embedder|.
219 for (PendingInfoBarRequests::iterator i = infobars_to_remove.begin(); 249 for (PendingInfobarRequests::iterator i = infobars_to_remove.begin();
220 i != infobars_to_remove.end(); ++i) 250 i != infobars_to_remove.end(); ++i)
221 GetInfoBarService(i->id())->RemoveInfoBar(i->infobar()); 251 GetInfoBarService(i->id())->RemoveInfoBar(i->infobar());
222 252
223 // Send out the permission notifications. 253 // Send out the permission notifications.
224 for (PendingInfoBarRequests::iterator i = requests_to_notify.begin(); 254 for (PendingInfobarRequests::iterator i = requests_to_notify.begin();
225 i != requests_to_notify.end(); ++i) 255 i != requests_to_notify.end(); ++i)
226 i->RunCallback(allowed); 256 i->RunCallback(allowed);
227 } 257 }
228 258
229 void PermissionQueueController::Observe( 259 void PermissionQueueController::Observe(
230 int type, 260 int type,
231 const content::NotificationSource& source, 261 const content::NotificationSource& source,
232 const content::NotificationDetails& details) { 262 const content::NotificationDetails& details) {
233 DCHECK_EQ(chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED, type); 263 DCHECK_EQ(chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED, type);
234 // We will receive this notification for all infobar closures, so we need to 264 // We will receive this notification for all infobar closures, so we need to
235 // check whether this is the geolocation infobar we're tracking. Note that the 265 // check whether this is the geolocation infobar we're tracking. Note that the
236 // InfoBarContainer (if any) may have received this notification before us and 266 // InfoBarContainer (if any) may have received this notification before us and
237 // caused the infobar to be deleted, so it's not safe to dereference the 267 // caused the infobar to be deleted, so it's not safe to dereference the
238 // contents of the infobar. The address of the infobar, however, is OK to 268 // contents of the infobar. The address of the infobar, however, is OK to
239 // use to find the PendingInfoBarRequest to remove because 269 // use to find the PendingInfobarRequest to remove because
240 // pending_infobar_requests_ will not have received any new entries between 270 // pending_infobar_requests_ will not have received any new entries between
241 // the NotificationService's call to InfoBarContainer::Observe and this 271 // the NotificationService's call to InfoBarContainer::Observe and this
242 // method. 272 // method.
243 InfoBar* infobar = content::Details<InfoBar::RemovedDetails>(details)->first; 273 InfoBar* infobar = content::Details<InfoBar::RemovedDetails>(details)->first;
244 for (PendingInfoBarRequests::iterator i = pending_infobar_requests_.begin(); 274 for (PendingInfobarRequests::iterator i = pending_infobar_requests_.begin();
245 i != pending_infobar_requests_.end(); ++i) { 275 i != pending_infobar_requests_.end(); ++i) {
246 if (i->infobar() == infobar) { 276 if (i->infobar() == infobar) {
247 PermissionRequestID id(i->id()); 277 PermissionRequestID id(i->id());
248 pending_infobar_requests_.erase(i); 278 pending_infobar_requests_.erase(i);
249 ShowQueuedInfoBarForTab(id); 279 ShowQueuedInfoBarForTab(id);
250 return; 280 return;
251 } 281 }
252 } 282 }
253 } 283 }
254 284
255 bool PermissionQueueController::AlreadyShowingInfoBarForTab( 285 bool PermissionQueueController::AlreadyShowingInfoBarForTab(
256 const PermissionRequestID& id) const { 286 const PermissionRequestID& id) const {
257 for (PendingInfoBarRequests::const_iterator i( 287 for (PendingInfobarRequests::const_iterator i(
258 pending_infobar_requests_.begin()); 288 pending_infobar_requests_.begin());
259 i != pending_infobar_requests_.end(); ++i) { 289 i != pending_infobar_requests_.end(); ++i) {
260 if (i->id().IsForSameTabAs(id) && i->has_infobar()) 290 if (i->id().IsForSameTabAs(id) && i->has_infobar())
261 return true; 291 return true;
262 } 292 }
263 return false; 293 return false;
264 } 294 }
265 295
266 void PermissionQueueController::ShowQueuedInfoBarForTab( 296 void PermissionQueueController::ShowQueuedInfoBarForTab(
267 const PermissionRequestID& id) { 297 const PermissionRequestID& id) {
268 DCHECK(!AlreadyShowingInfoBarForTab(id)); 298 DCHECK(!AlreadyShowingInfoBarForTab(id));
269 299
270 // We can get here for example during tab shutdown, when the InfoBarService is 300 // We can get here for example during tab shutdown, when the InfoBarService is
271 // removing all existing infobars, thus calling back to Observe(). In this 301 // removing all existing infobars, thus calling back to Observe(). In this
272 // case the service still exists, and is supplied as the source of the 302 // case the service still exists, and is supplied as the source of the
273 // notification we observed, but is no longer accessible from its WebContents. 303 // notification we observed, but is no longer accessible from its WebContents.
274 // In this case we should just go ahead and cancel further infobars for this 304 // In this case we should just go ahead and cancel further infobars for this
275 // tab instead of trying to access the service. 305 // tab instead of trying to access the service.
276 // 306 //
277 // Similarly, if we're being destroyed, we should also avoid showing further 307 // Similarly, if we're being destroyed, we should also avoid showing further
278 // infobars. 308 // infobars.
279 InfoBarService* infobar_service = GetInfoBarService(id); 309 InfoBarService* infobar_service = GetInfoBarService(id);
280 if (!infobar_service || in_shutdown_) { 310 if (!infobar_service || in_shutdown_) {
281 ClearPendingInfoBarRequestsForTab(id); 311 ClearPendingInfobarRequestsForTab(id);
282 return; 312 return;
283 } 313 }
284 314
285 for (PendingInfoBarRequests::iterator i = pending_infobar_requests_.begin(); 315 for (PendingInfobarRequests::iterator i = pending_infobar_requests_.begin();
286 i != pending_infobar_requests_.end(); ++i) { 316 i != pending_infobar_requests_.end(); ++i) {
287 if (i->id().IsForSameTabAs(id) && !i->has_infobar()) { 317 if (i->id().IsForSameTabAs(id) && !i->has_infobar()) {
288 RegisterForInfoBarNotifications(infobar_service); 318 RegisterForInfoBarNotifications(infobar_service);
289 i->CreateInfoBar( 319 i->CreateInfoBar(
290 this, profile_->GetPrefs()->GetString(prefs::kAcceptLanguages)); 320 this, profile_->GetPrefs()->GetString(prefs::kAcceptLanguages));
291 return; 321 return;
292 } 322 }
293 } 323 }
294 324
295 UnregisterForInfoBarNotifications(infobar_service); 325 UnregisterForInfoBarNotifications(infobar_service);
296 } 326 }
297 327
298 void PermissionQueueController::ClearPendingInfoBarRequestsForTab( 328 void PermissionQueueController::ClearPendingInfobarRequestsForTab(
299 const PermissionRequestID& id) { 329 const PermissionRequestID& id) {
300 for (PendingInfoBarRequests::iterator i = pending_infobar_requests_.begin(); 330 for (PendingInfobarRequests::iterator i = pending_infobar_requests_.begin();
301 i != pending_infobar_requests_.end(); ) { 331 i != pending_infobar_requests_.end(); ) {
302 if (i->id().IsForSameTabAs(id)) { 332 if (i->id().IsForSameTabAs(id)) {
303 DCHECK(!i->has_infobar()); 333 DCHECK(!i->has_infobar());
304 i = pending_infobar_requests_.erase(i); 334 i = pending_infobar_requests_.erase(i);
305 } else { 335 } else {
306 ++i; 336 ++i;
307 } 337 }
308 } 338 }
309 } 339 }
310 340
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
343 373
344 ContentSetting content_setting = 374 ContentSetting content_setting =
345 allowed ? CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK; 375 allowed ? CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK;
346 profile_->GetHostContentSettingsMap()->SetContentSetting( 376 profile_->GetHostContentSettingsMap()->SetContentSetting(
347 ContentSettingsPattern::FromURLNoWildcard(requesting_frame.GetOrigin()), 377 ContentSettingsPattern::FromURLNoWildcard(requesting_frame.GetOrigin()),
348 ContentSettingsPattern::FromURLNoWildcard(embedder.GetOrigin()), 378 ContentSettingsPattern::FromURLNoWildcard(embedder.GetOrigin()),
349 type_, 379 type_,
350 std::string(), 380 std::string(),
351 content_setting); 381 content_setting);
352 } 382 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698