| OLD | NEW |
| 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/permissions/permission_queue_controller.h" | 5 #include "chrome/browser/permissions/permission_queue_controller.h" |
| 6 | 6 |
| 7 #include "base/feature_list.h" |
| 7 #include "chrome/browser/chrome_notification_types.h" | 8 #include "chrome/browser/chrome_notification_types.h" |
| 8 #include "chrome/browser/content_settings/host_content_settings_map_factory.h" | 9 #include "chrome/browser/content_settings/host_content_settings_map_factory.h" |
| 9 #include "chrome/browser/infobars/infobar_service.h" | 10 #include "chrome/browser/infobars/infobar_service.h" |
| 11 #include "chrome/browser/permissions/permission_dialog_delegate.h" |
| 10 #include "chrome/browser/permissions/permission_infobar_delegate.h" | 12 #include "chrome/browser/permissions/permission_infobar_delegate.h" |
| 11 #include "chrome/browser/permissions/permission_request.h" | 13 #include "chrome/browser/permissions/permission_request.h" |
| 12 #include "chrome/browser/permissions/permission_request_id.h" | 14 #include "chrome/browser/permissions/permission_request_id.h" |
| 13 #include "chrome/browser/permissions/permission_uma_util.h" | 15 #include "chrome/browser/permissions/permission_uma_util.h" |
| 14 #include "chrome/browser/profiles/profile.h" | 16 #include "chrome/browser/profiles/profile.h" |
| 15 #include "chrome/browser/tab_contents/tab_util.h" | 17 #include "chrome/browser/tab_contents/tab_util.h" |
| 18 #include "chrome/common/chrome_features.h" |
| 16 #include "components/content_settings/core/browser/host_content_settings_map.h" | 19 #include "components/content_settings/core/browser/host_content_settings_map.h" |
| 17 #include "components/content_settings/core/common/content_settings.h" | 20 #include "components/content_settings/core/common/content_settings.h" |
| 18 #include "components/infobars/core/infobar.h" | 21 #include "components/infobars/core/infobar.h" |
| 19 #include "content/public/browser/browser_thread.h" | 22 #include "content/public/browser/browser_thread.h" |
| 20 #include "content/public/browser/notification_details.h" | 23 #include "content/public/browser/notification_details.h" |
| 21 #include "content/public/browser/notification_source.h" | 24 #include "content/public/browser/notification_source.h" |
| 22 #include "content/public/browser/notification_types.h" | 25 #include "content/public/browser/notification_types.h" |
| 23 #include "content/public/browser/web_contents.h" | 26 #include "content/public/browser/web_contents.h" |
| 24 #include "content/public/common/url_constants.h" | 27 #include "content/public/common/url_constants.h" |
| 25 | 28 |
| 26 namespace { | 29 namespace { |
| 27 | 30 |
| 31 content::WebContents* GetWebContents(const PermissionRequestID& id) { |
| 32 return tab_util::GetWebContentsByFrameID( |
| 33 id.render_process_id(), id.render_frame_id()); |
| 34 } |
| 35 |
| 36 |
| 28 InfoBarService* GetInfoBarService(const PermissionRequestID& id) { | 37 InfoBarService* GetInfoBarService(const PermissionRequestID& id) { |
| 29 content::WebContents* web_contents = tab_util::GetWebContentsByFrameID( | 38 content::WebContents* web_contents = GetWebContents(id); |
| 30 id.render_process_id(), id.render_frame_id()); | 39 return web_contents ? InfoBarService::FromWebContents(web_contents) : nullptr; |
| 31 return web_contents ? InfoBarService::FromWebContents(web_contents) : NULL; | |
| 32 } | 40 } |
| 33 | 41 |
| 34 bool ArePermissionRequestsForSameTab( | 42 bool ArePermissionRequestsForSameTab( |
| 35 const PermissionRequestID& request, | 43 const PermissionRequestID& request, |
| 36 const PermissionRequestID& other_request) { | 44 const PermissionRequestID& other_request) { |
| 37 content::WebContents* web_contents = tab_util::GetWebContentsByFrameID( | 45 content::WebContents* web_contents = tab_util::GetWebContentsByFrameID( |
| 38 request.render_process_id(), request.render_frame_id()); | 46 request.render_process_id(), request.render_frame_id()); |
| 39 content::WebContents* other_web_contents = tab_util::GetWebContentsByFrameID( | 47 content::WebContents* other_web_contents = tab_util::GetWebContentsByFrameID( |
| 40 other_request.render_process_id(), other_request.render_frame_id()); | 48 other_request.render_process_id(), other_request.render_frame_id()); |
| 41 | 49 |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 87 bool user_gesture, | 95 bool user_gesture, |
| 88 Profile* profile, | 96 Profile* profile, |
| 89 const PermissionDecidedCallback& callback) | 97 const PermissionDecidedCallback& callback) |
| 90 : type_(type), | 98 : type_(type), |
| 91 id_(id), | 99 id_(id), |
| 92 requesting_frame_(requesting_frame), | 100 requesting_frame_(requesting_frame), |
| 93 embedder_(embedder), | 101 embedder_(embedder), |
| 94 user_gesture_(user_gesture), | 102 user_gesture_(user_gesture), |
| 95 profile_(profile), | 103 profile_(profile), |
| 96 callback_(callback), | 104 callback_(callback), |
| 97 infobar_(NULL) {} | 105 infobar_(nullptr) {} |
| 98 | 106 |
| 99 PermissionQueueController::PendingInfobarRequest::~PendingInfobarRequest() { | 107 PermissionQueueController::PendingInfobarRequest::~PendingInfobarRequest() { |
| 100 } | 108 } |
| 101 | 109 |
| 102 bool PermissionQueueController::PendingInfobarRequest::IsForPair( | 110 bool PermissionQueueController::PendingInfobarRequest::IsForPair( |
| 103 const GURL& requesting_frame, | 111 const GURL& requesting_frame, |
| 104 const GURL& embedder) const { | 112 const GURL& embedder) const { |
| 105 return (requesting_frame_ == requesting_frame) && (embedder_ == embedder); | 113 return (requesting_frame_ == requesting_frame) && (embedder_ == embedder); |
| 106 } | 114 } |
| 107 | 115 |
| 108 void PermissionQueueController::PendingInfobarRequest::RunCallback( | 116 void PermissionQueueController::PendingInfobarRequest::RunCallback( |
| 109 ContentSetting content_setting) { | 117 ContentSetting content_setting) { |
| 110 callback_.Run(content_setting); | 118 callback_.Run(content_setting); |
| 111 } | 119 } |
| 112 | 120 |
| 113 void PermissionQueueController::PendingInfobarRequest::CreateInfoBar( | 121 void PermissionQueueController::PendingInfobarRequest::CreateInfoBar( |
| 114 PermissionQueueController* controller) { | 122 PermissionQueueController* controller) { |
| 115 // Controller can be Unretained because the lifetime of the infobar | 123 // Controller can be Unretained because the lifetime of the infobar |
| 116 // is tied to that of the queue controller. Before QueueController | 124 // is tied to that of the queue controller. Before QueueController |
| 117 // is destroyed, all requests will be cancelled and so all delegates | 125 // is destroyed, all requests will be cancelled and so all delegates |
| 118 // will be destroyed. | 126 // will be destroyed. |
| 119 PermissionInfoBarDelegate::PermissionSetCallback callback = base::Bind( | 127 PermissionInfoBarDelegate::PermissionSetCallback callback = base::Bind( |
| 120 &PermissionQueueController::OnPermissionSet, base::Unretained(controller), | 128 &PermissionQueueController::OnPermissionSet, base::Unretained(controller), |
| 121 id_, requesting_frame_, embedder_, user_gesture_); | 129 id_, requesting_frame_, embedder_, user_gesture_); |
| 122 | 130 |
| 123 infobar_ = PermissionInfoBarDelegate::Create(type_, GetInfoBarService(id_), | 131 if (base::FeatureList::IsEnabled(features::kModalPermissionPrompts)) { |
| 124 requesting_frame_, user_gesture_, | 132 // Only one modal can be shown at a time. This method calls through to Java, |
| 125 profile_, callback); | 133 // which owns and manages the queue of modal prompts; the bookkeeping in |
| 134 // this class will work as expected: |
| 135 // i. no pending request will ever have an infobar created for it. |
| 136 // ii. OnPermissionSet is still called when the user makes a decision. |
| 137 PermissionDialogDelegate::Create(type_, GetWebContents(id_), |
| 138 requesting_frame_, user_gesture_, profile_, |
| 139 callback); |
| 140 } else { |
| 141 infobar_ = PermissionInfoBarDelegate::Create( |
| 142 type_, GetInfoBarService(id_), requesting_frame_, user_gesture_, |
| 143 profile_, callback); |
| 144 } |
| 126 } | 145 } |
| 127 | 146 |
| 128 PermissionQueueController::PermissionQueueController( | 147 PermissionQueueController::PermissionQueueController( |
| 129 Profile* profile, | 148 Profile* profile, |
| 130 content::PermissionType permission_type, | 149 content::PermissionType permission_type, |
| 131 ContentSettingsType content_settings_type) | 150 ContentSettingsType content_settings_type) |
| 132 : profile_(profile), | 151 : profile_(profile), |
| 133 permission_type_(permission_type), | 152 permission_type_(permission_type), |
| 134 content_settings_type_(content_settings_type), | 153 content_settings_type_(content_settings_type), |
| 135 in_shutdown_(false) {} | 154 in_shutdown_(false) {} |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 214 // Cancel this request first, then notify listeners. TODO(pkasting): Why | 233 // Cancel this request first, then notify listeners. TODO(pkasting): Why |
| 215 // is this order important? | 234 // is this order important? |
| 216 PendingInfobarRequests requests_to_notify; | 235 PendingInfobarRequests requests_to_notify; |
| 217 PendingInfobarRequests infobars_to_remove; | 236 PendingInfobarRequests infobars_to_remove; |
| 218 std::vector<PendingInfobarRequests::iterator> pending_requests_to_remove; | 237 std::vector<PendingInfobarRequests::iterator> pending_requests_to_remove; |
| 219 for (PendingInfobarRequests::iterator i = pending_infobar_requests_.begin(); | 238 for (PendingInfobarRequests::iterator i = pending_infobar_requests_.begin(); |
| 220 i != pending_infobar_requests_.end(); ++i) { | 239 i != pending_infobar_requests_.end(); ++i) { |
| 221 if (!i->IsForPair(requesting_frame, embedder)) | 240 if (!i->IsForPair(requesting_frame, embedder)) |
| 222 continue; | 241 continue; |
| 223 requests_to_notify.push_back(*i); | 242 requests_to_notify.push_back(*i); |
| 224 if (!i->has_infobar()) { | 243 if (!i->has_infobar() || |
| 225 // We haven't created an infobar yet, just record the pending request | 244 base::FeatureList::IsEnabled(features::kModalPermissionPrompts)) { |
| 226 // index and remove it later. | 245 // We haven't created an infobar yet, or no infobars are being created. |
| 246 // Record the pending request index and remove it later. |
| 227 pending_requests_to_remove.push_back(i); | 247 pending_requests_to_remove.push_back(i); |
| 228 continue; | 248 continue; |
| 229 } | 249 } |
| 230 if (id == i->id()) { | 250 if (id == i->id()) { |
| 231 // The infobar that called us is i->infobar(), and its delegate is | 251 // The infobar that called us is i->infobar(), and its delegate is |
| 232 // currently in either Accept() or Cancel(). This means that | 252 // currently in either Accept() or Cancel(). This means that |
| 233 // RemoveInfoBar() will be called later on, and that will trigger a | 253 // RemoveInfoBar() will be called later on, and that will trigger a |
| 234 // notification we're observing. | 254 // notification we're observing. |
| 235 continue; | 255 continue; |
| 236 } | 256 } |
| (...skipping 16 matching lines...) Expand all Loading... |
| 253 ContentSetting content_setting = CONTENT_SETTING_DEFAULT; | 273 ContentSetting content_setting = CONTENT_SETTING_DEFAULT; |
| 254 if (decision == GRANTED) | 274 if (decision == GRANTED) |
| 255 content_setting = CONTENT_SETTING_ALLOW; | 275 content_setting = CONTENT_SETTING_ALLOW; |
| 256 else if (decision == DENIED) | 276 else if (decision == DENIED) |
| 257 content_setting = CONTENT_SETTING_BLOCK; | 277 content_setting = CONTENT_SETTING_BLOCK; |
| 258 else | 278 else |
| 259 DCHECK_EQ(DISMISSED, decision); | 279 DCHECK_EQ(DISMISSED, decision); |
| 260 | 280 |
| 261 // Send out the permission notifications. | 281 // Send out the permission notifications. |
| 262 for (PendingInfobarRequests::iterator i = requests_to_notify.begin(); | 282 for (PendingInfobarRequests::iterator i = requests_to_notify.begin(); |
| 263 i != requests_to_notify.end(); ++i) | 283 i != requests_to_notify.end(); ++i) { |
| 264 i->RunCallback(content_setting); | 284 i->RunCallback(content_setting); |
| 285 } |
| 265 | 286 |
| 266 // Remove the pending requests in reverse order. | 287 // Remove the pending requests in reverse order. |
| 267 for (int i = pending_requests_to_remove.size() - 1; i >= 0; --i) | 288 for (int i = pending_requests_to_remove.size() - 1; i >= 0; --i) |
| 268 pending_infobar_requests_.erase(pending_requests_to_remove[i]); | 289 pending_infobar_requests_.erase(pending_requests_to_remove[i]); |
| 269 } | 290 } |
| 270 | 291 |
| 271 void PermissionQueueController::Observe( | 292 void PermissionQueueController::Observe( |
| 272 int type, | 293 int type, |
| 273 const content::NotificationSource& source, | 294 const content::NotificationSource& source, |
| 274 const content::NotificationDetails& details) { | 295 const content::NotificationDetails& details) { |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 321 // infobars. | 342 // infobars. |
| 322 InfoBarService* infobar_service = GetInfoBarService(id); | 343 InfoBarService* infobar_service = GetInfoBarService(id); |
| 323 if (!infobar_service || in_shutdown_) { | 344 if (!infobar_service || in_shutdown_) { |
| 324 ClearPendingInfobarRequestsForTab(id); | 345 ClearPendingInfobarRequestsForTab(id); |
| 325 return; | 346 return; |
| 326 } | 347 } |
| 327 | 348 |
| 328 for (PendingInfobarRequests::iterator i = pending_infobar_requests_.begin(); | 349 for (PendingInfobarRequests::iterator i = pending_infobar_requests_.begin(); |
| 329 i != pending_infobar_requests_.end(); ++i) { | 350 i != pending_infobar_requests_.end(); ++i) { |
| 330 if (ArePermissionRequestsForSameTab(i->id(), id) && !i->has_infobar()) { | 351 if (ArePermissionRequestsForSameTab(i->id(), id) && !i->has_infobar()) { |
| 331 RegisterForInfoBarNotifications(infobar_service); | 352 // When using modal permission prompts, Java controls the display queue, |
| 353 // so infobar notifications are not relevant. |
| 354 if (!base::FeatureList::IsEnabled(features::kModalPermissionPrompts)) |
| 355 RegisterForInfoBarNotifications(infobar_service); |
| 356 |
| 332 i->CreateInfoBar(this); | 357 i->CreateInfoBar(this); |
| 333 return; | 358 return; |
| 334 } | 359 } |
| 335 } | 360 } |
| 336 | 361 |
| 337 UnregisterForInfoBarNotifications(infobar_service); | 362 UnregisterForInfoBarNotifications(infobar_service); |
| 338 } | 363 } |
| 339 | 364 |
| 340 void PermissionQueueController::ClearPendingInfobarRequestsForTab( | 365 void PermissionQueueController::ClearPendingInfobarRequestsForTab( |
| 341 const PermissionRequestID& id) { | 366 const PermissionRequestID& id) { |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 385 } | 410 } |
| 386 | 411 |
| 387 ContentSetting content_setting = | 412 ContentSetting content_setting = |
| 388 (decision == GRANTED) ? CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK; | 413 (decision == GRANTED) ? CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK; |
| 389 | 414 |
| 390 HostContentSettingsMapFactory::GetForProfile(profile_) | 415 HostContentSettingsMapFactory::GetForProfile(profile_) |
| 391 ->SetContentSettingDefaultScope( | 416 ->SetContentSettingDefaultScope( |
| 392 requesting_frame.GetOrigin(), embedder.GetOrigin(), | 417 requesting_frame.GetOrigin(), embedder.GetOrigin(), |
| 393 content_settings_type_, std::string(), content_setting); | 418 content_settings_type_, std::string(), content_setting); |
| 394 } | 419 } |
| OLD | NEW |