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

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

Issue 2446063002: Implement a modal permission dialog on Android gated by a feature. (Closed)
Patch Set: Rebase Created 4 years, 1 month 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/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
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698