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

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: Move delegate creation and dispatch into constructor 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 "chrome/browser/chrome_notification_types.h" 7 #include "chrome/browser/chrome_notification_types.h"
8 #include "chrome/browser/content_settings/host_content_settings_map_factory.h" 8 #include "chrome/browser/content_settings/host_content_settings_map_factory.h"
9 #include "chrome/browser/infobars/infobar_service.h" 9 #include "chrome/browser/infobars/infobar_service.h"
10 #include "chrome/browser/permissions/permission_dialog_delegate.h"
10 #include "chrome/browser/permissions/permission_infobar_delegate.h" 11 #include "chrome/browser/permissions/permission_infobar_delegate.h"
11 #include "chrome/browser/permissions/permission_request.h" 12 #include "chrome/browser/permissions/permission_request.h"
12 #include "chrome/browser/permissions/permission_request_id.h" 13 #include "chrome/browser/permissions/permission_request_id.h"
13 #include "chrome/browser/permissions/permission_uma_util.h" 14 #include "chrome/browser/permissions/permission_uma_util.h"
14 #include "chrome/browser/profiles/profile.h" 15 #include "chrome/browser/profiles/profile.h"
15 #include "chrome/browser/tab_contents/tab_util.h" 16 #include "chrome/browser/tab_contents/tab_util.h"
16 #include "components/content_settings/core/browser/host_content_settings_map.h" 17 #include "components/content_settings/core/browser/host_content_settings_map.h"
17 #include "components/content_settings/core/common/content_settings.h" 18 #include "components/content_settings/core/common/content_settings.h"
18 #include "components/infobars/core/infobar.h" 19 #include "components/infobars/core/infobar.h"
19 #include "content/public/browser/browser_thread.h" 20 #include "content/public/browser/browser_thread.h"
20 #include "content/public/browser/notification_details.h" 21 #include "content/public/browser/notification_details.h"
21 #include "content/public/browser/notification_source.h" 22 #include "content/public/browser/notification_source.h"
22 #include "content/public/browser/notification_types.h" 23 #include "content/public/browser/notification_types.h"
23 #include "content/public/browser/web_contents.h" 24 #include "content/public/browser/web_contents.h"
24 #include "content/public/common/url_constants.h" 25 #include "content/public/common/url_constants.h"
25 26
26 namespace { 27 namespace {
27 28
29 content::WebContents* GetWebContents(const PermissionRequestID& id) {
30 return tab_util::GetWebContentsByFrameID(
31 id.render_process_id(), id.render_frame_id());
32 }
33
34
28 InfoBarService* GetInfoBarService(const PermissionRequestID& id) { 35 InfoBarService* GetInfoBarService(const PermissionRequestID& id) {
29 content::WebContents* web_contents = tab_util::GetWebContentsByFrameID( 36 content::WebContents* web_contents = GetWebContents(id);
30 id.render_process_id(), id.render_frame_id()); 37 return web_contents ? InfoBarService::FromWebContents(web_contents) : nullptr;
31 return web_contents ? InfoBarService::FromWebContents(web_contents) : NULL;
32 } 38 }
33 39
34 bool ArePermissionRequestsForSameTab( 40 bool ArePermissionRequestsForSameTab(
35 const PermissionRequestID& request, 41 const PermissionRequestID& request,
36 const PermissionRequestID& other_request) { 42 const PermissionRequestID& other_request) {
37 content::WebContents* web_contents = tab_util::GetWebContentsByFrameID( 43 content::WebContents* web_contents = tab_util::GetWebContentsByFrameID(
38 request.render_process_id(), request.render_frame_id()); 44 request.render_process_id(), request.render_frame_id());
39 content::WebContents* other_web_contents = tab_util::GetWebContentsByFrameID( 45 content::WebContents* other_web_contents = tab_util::GetWebContentsByFrameID(
40 other_request.render_process_id(), other_request.render_frame_id()); 46 other_request.render_process_id(), other_request.render_frame_id());
41 47
(...skipping 11 matching lines...) Expand all
53 bool user_gesture, 59 bool user_gesture,
54 Profile* profile, 60 Profile* profile,
55 const PermissionDecidedCallback& callback); 61 const PermissionDecidedCallback& callback);
56 ~PendingInfobarRequest(); 62 ~PendingInfobarRequest();
57 63
58 bool IsForPair(const GURL& requesting_frame, 64 bool IsForPair(const GURL& requesting_frame,
59 const GURL& embedder) const; 65 const GURL& embedder) const;
60 66
61 const PermissionRequestID& id() const { return id_; } 67 const PermissionRequestID& id() const { return id_; }
62 const GURL& requesting_frame() const { return requesting_frame_; } 68 const GURL& requesting_frame() const { return requesting_frame_; }
69 bool has_gesture() const { return user_gesture_; }
63 bool has_infobar() const { return !!infobar_; } 70 bool has_infobar() const { return !!infobar_; }
71 bool has_dialog() const { return has_dialog_; }
64 infobars::InfoBar* infobar() { return infobar_; } 72 infobars::InfoBar* infobar() { return infobar_; }
65 73
66 void RunCallback(ContentSetting content_setting); 74 void RunCallback(ContentSetting content_setting);
67 void CreateInfoBar(PermissionQueueController* controller); 75 void CreatePrompt(PermissionQueueController* controller, bool show_dialog);
68 76
69 private: 77 private:
70 content::PermissionType type_; 78 content::PermissionType type_;
71 PermissionRequestID id_; 79 PermissionRequestID id_;
72 GURL requesting_frame_; 80 GURL requesting_frame_;
73 GURL embedder_; 81 GURL embedder_;
74 bool user_gesture_; 82 bool user_gesture_;
75 Profile* profile_; 83 Profile* profile_;
76 PermissionDecidedCallback callback_; 84 PermissionDecidedCallback callback_;
77 infobars::InfoBar* infobar_; 85 infobars::InfoBar* infobar_;
86 bool has_dialog_;
78 87
79 // Purposefully do not disable copying, as this is stored in STL containers. 88 // Purposefully do not disable copying, as this is stored in STL containers.
80 }; 89 };
81 90
82 PermissionQueueController::PendingInfobarRequest::PendingInfobarRequest( 91 PermissionQueueController::PendingInfobarRequest::PendingInfobarRequest(
83 content::PermissionType type, 92 content::PermissionType type,
84 const PermissionRequestID& id, 93 const PermissionRequestID& id,
85 const GURL& requesting_frame, 94 const GURL& requesting_frame,
86 const GURL& embedder, 95 const GURL& embedder,
87 bool user_gesture, 96 bool user_gesture,
88 Profile* profile, 97 Profile* profile,
89 const PermissionDecidedCallback& callback) 98 const PermissionDecidedCallback& callback)
90 : type_(type), 99 : type_(type),
91 id_(id), 100 id_(id),
92 requesting_frame_(requesting_frame), 101 requesting_frame_(requesting_frame),
93 embedder_(embedder), 102 embedder_(embedder),
94 user_gesture_(user_gesture), 103 user_gesture_(user_gesture),
95 profile_(profile), 104 profile_(profile),
96 callback_(callback), 105 callback_(callback),
97 infobar_(NULL) {} 106 infobar_(nullptr),
107 has_dialog_(false) {}
98 108
99 PermissionQueueController::PendingInfobarRequest::~PendingInfobarRequest() { 109 PermissionQueueController::PendingInfobarRequest::~PendingInfobarRequest() {
100 } 110 }
101 111
102 bool PermissionQueueController::PendingInfobarRequest::IsForPair( 112 bool PermissionQueueController::PendingInfobarRequest::IsForPair(
103 const GURL& requesting_frame, 113 const GURL& requesting_frame,
104 const GURL& embedder) const { 114 const GURL& embedder) const {
105 return (requesting_frame_ == requesting_frame) && (embedder_ == embedder); 115 return (requesting_frame_ == requesting_frame) && (embedder_ == embedder);
106 } 116 }
107 117
108 void PermissionQueueController::PendingInfobarRequest::RunCallback( 118 void PermissionQueueController::PendingInfobarRequest::RunCallback(
109 ContentSetting content_setting) { 119 ContentSetting content_setting) {
110 callback_.Run(content_setting); 120 callback_.Run(content_setting);
111 } 121 }
112 122
113 void PermissionQueueController::PendingInfobarRequest::CreateInfoBar( 123 void PermissionQueueController::PendingInfobarRequest::CreatePrompt(
114 PermissionQueueController* controller) { 124 PermissionQueueController* controller,
125 bool show_dialog) {
115 // Controller can be Unretained because the lifetime of the infobar 126 // Controller can be Unretained because the lifetime of the infobar
116 // is tied to that of the queue controller. Before QueueController 127 // is tied to that of the queue controller. Before QueueController
117 // is destroyed, all requests will be cancelled and so all delegates 128 // is destroyed, all requests will be cancelled and so all delegates
118 // will be destroyed. 129 // will be destroyed.
119 PermissionInfoBarDelegate::PermissionSetCallback callback = base::Bind( 130 PermissionInfoBarDelegate::PermissionSetCallback callback = base::Bind(
120 &PermissionQueueController::OnPermissionSet, base::Unretained(controller), 131 &PermissionQueueController::OnPermissionSet, base::Unretained(controller),
121 id_, requesting_frame_, embedder_, user_gesture_); 132 id_, requesting_frame_, embedder_, user_gesture_);
122 133
123 infobar_ = PermissionInfoBarDelegate::Create(type_, GetInfoBarService(id_), 134 if (show_dialog) {
124 requesting_frame_, user_gesture_, 135 // We should show a dialog prompt instead of an infobar. Since only one
125 profile_, callback); 136 // dialog can be shown at a time, the Java-side owns and manages the queue
137 // of prompts; the bookkeeping in this class will work as expected:
138 // i. no pending request will ever have an infobar created for it.
139 // ii. OnPermissionSet is still called when the user makes a decision.
140 has_dialog_ = true;
141 PermissionDialogDelegate::Create(GetWebContents(id_), type_,
142 requesting_frame_, user_gesture_, profile_,
143 callback);
144 } else {
145 infobar_ = PermissionInfoBarDelegate::Create(
146 GetInfoBarService(id_), type_, requesting_frame_, user_gesture_,
147 profile_, callback);
148 }
126 } 149 }
127 150
128 PermissionQueueController::PermissionQueueController( 151 PermissionQueueController::PermissionQueueController(
129 Profile* profile, 152 Profile* profile,
130 content::PermissionType permission_type, 153 content::PermissionType permission_type,
131 ContentSettingsType content_settings_type) 154 ContentSettingsType content_settings_type)
132 : profile_(profile), 155 : profile_(profile),
133 permission_type_(permission_type), 156 permission_type_(permission_type),
134 content_settings_type_(content_settings_type), 157 content_settings_type_(content_settings_type),
135 in_shutdown_(false) {} 158 in_shutdown_(false) {}
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
253 ContentSetting content_setting = CONTENT_SETTING_DEFAULT; 276 ContentSetting content_setting = CONTENT_SETTING_DEFAULT;
254 if (decision == GRANTED) 277 if (decision == GRANTED)
255 content_setting = CONTENT_SETTING_ALLOW; 278 content_setting = CONTENT_SETTING_ALLOW;
256 else if (decision == DENIED) 279 else if (decision == DENIED)
257 content_setting = CONTENT_SETTING_BLOCK; 280 content_setting = CONTENT_SETTING_BLOCK;
258 else 281 else
259 DCHECK_EQ(DISMISSED, decision); 282 DCHECK_EQ(DISMISSED, decision);
260 283
261 // Send out the permission notifications. 284 // Send out the permission notifications.
262 for (PendingInfobarRequests::iterator i = requests_to_notify.begin(); 285 for (PendingInfobarRequests::iterator i = requests_to_notify.begin();
263 i != requests_to_notify.end(); ++i) 286 i != requests_to_notify.end(); ++i) {
264 i->RunCallback(content_setting); 287 i->RunCallback(content_setting);
288 }
265 289
266 // Remove the pending requests in reverse order. 290 // Remove the pending requests in reverse order.
267 for (int i = pending_requests_to_remove.size() - 1; i >= 0; --i) 291 for (int i = pending_requests_to_remove.size() - 1; i >= 0; --i)
268 pending_infobar_requests_.erase(pending_requests_to_remove[i]); 292 pending_infobar_requests_.erase(pending_requests_to_remove[i]);
269 } 293 }
270 294
271 void PermissionQueueController::Observe( 295 void PermissionQueueController::Observe(
272 int type, 296 int type,
273 const content::NotificationSource& source, 297 const content::NotificationSource& source,
274 const content::NotificationDetails& details) { 298 const content::NotificationDetails& details) {
(...skipping 18 matching lines...) Expand all
293 return; 317 return;
294 } 318 }
295 } 319 }
296 } 320 }
297 321
298 bool PermissionQueueController::AlreadyShowingInfoBarForTab( 322 bool PermissionQueueController::AlreadyShowingInfoBarForTab(
299 const PermissionRequestID& id) const { 323 const PermissionRequestID& id) const {
300 for (PendingInfobarRequests::const_iterator i( 324 for (PendingInfobarRequests::const_iterator i(
301 pending_infobar_requests_.begin()); 325 pending_infobar_requests_.begin());
302 i != pending_infobar_requests_.end(); ++i) { 326 i != pending_infobar_requests_.end(); ++i) {
303 if (ArePermissionRequestsForSameTab(i->id(), id) && i->has_infobar()) 327 if (ArePermissionRequestsForSameTab(i->id(), id) &&
328 (i->has_infobar() || i->has_dialog())) {
304 return true; 329 return true;
330 }
305 } 331 }
306 return false; 332 return false;
307 } 333 }
308 334
309 void PermissionQueueController::ShowQueuedInfoBarForTab( 335 void PermissionQueueController::ShowQueuedInfoBarForTab(
310 const PermissionRequestID& id) { 336 const PermissionRequestID& id) {
311 DCHECK(!AlreadyShowingInfoBarForTab(id)); 337 DCHECK(!AlreadyShowingInfoBarForTab(id));
312 338
313 // We can get here for example during tab shutdown, when the InfoBarService is 339 // We can get here for example during tab shutdown, when the InfoBarService is
314 // removing all existing infobars, thus calling back to Observe(). In this 340 // removing all existing infobars, thus calling back to Observe(). In this
315 // case the service still exists, and is supplied as the source of the 341 // case the service still exists, and is supplied as the source of the
316 // notification we observed, but is no longer accessible from its WebContents. 342 // notification we observed, but is no longer accessible from its WebContents.
317 // In this case we should just go ahead and cancel further infobars for this 343 // In this case we should just go ahead and cancel further infobars for this
318 // tab instead of trying to access the service. 344 // tab instead of trying to access the service.
319 // 345 //
320 // Similarly, if we're being destroyed, we should also avoid showing further 346 // Similarly, if we're being destroyed, we should also avoid showing further
321 // infobars. 347 // infobars.
322 InfoBarService* infobar_service = GetInfoBarService(id); 348 InfoBarService* infobar_service = GetInfoBarService(id);
323 if (!infobar_service || in_shutdown_) { 349 if (!infobar_service || in_shutdown_) {
324 ClearPendingInfobarRequestsForTab(id); 350 ClearPendingInfobarRequestsForTab(id);
325 return; 351 return;
326 } 352 }
327 353
328 for (PendingInfobarRequests::iterator i = pending_infobar_requests_.begin(); 354 for (PendingInfobarRequests::iterator i = pending_infobar_requests_.begin();
329 i != pending_infobar_requests_.end(); ++i) { 355 i != pending_infobar_requests_.end(); ++i) {
330 if (ArePermissionRequestsForSameTab(i->id(), id) && !i->has_infobar()) { 356 if (ArePermissionRequestsForSameTab(i->id(), id) && !i->has_infobar()) {
331 RegisterForInfoBarNotifications(infobar_service); 357 // When using modal permission prompts, Java controls the display queue,
332 i->CreateInfoBar(this); 358 // so infobar notifications are not relevant.
359 bool show_dialog =
360 PermissionDialogDelegate::ShouldShowDialog(i->has_gesture());
361 if (!show_dialog)
362 RegisterForInfoBarNotifications(infobar_service);
363
364 i->CreatePrompt(this, show_dialog);
333 return; 365 return;
334 } 366 }
335 } 367 }
336 368
337 UnregisterForInfoBarNotifications(infobar_service); 369 UnregisterForInfoBarNotifications(infobar_service);
338 } 370 }
339 371
340 void PermissionQueueController::ClearPendingInfobarRequestsForTab( 372 void PermissionQueueController::ClearPendingInfobarRequestsForTab(
341 const PermissionRequestID& id) { 373 const PermissionRequestID& id) {
342 for (PendingInfobarRequests::iterator i = pending_infobar_requests_.begin(); 374 for (PendingInfobarRequests::iterator i = pending_infobar_requests_.begin();
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
385 } 417 }
386 418
387 ContentSetting content_setting = 419 ContentSetting content_setting =
388 (decision == GRANTED) ? CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK; 420 (decision == GRANTED) ? CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK;
389 421
390 HostContentSettingsMapFactory::GetForProfile(profile_) 422 HostContentSettingsMapFactory::GetForProfile(profile_)
391 ->SetContentSettingDefaultScope( 423 ->SetContentSettingDefaultScope(
392 requesting_frame.GetOrigin(), embedder.GetOrigin(), 424 requesting_frame.GetOrigin(), embedder.GetOrigin(),
393 content_settings_type_, std::string(), content_setting); 425 content_settings_type_, std::string(), content_setting);
394 } 426 }
OLDNEW
« no previous file with comments | « chrome/browser/permissions/permission_infobar_delegate.cc ('k') | chrome/common/chrome_features.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698