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 "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/geolocation/geolocation_infobar_delegate_android.h" | 9 #include "chrome/browser/geolocation/geolocation_infobar_delegate_android.h" |
10 #include "chrome/browser/infobars/infobar_service.h" | 10 #include "chrome/browser/infobars/infobar_service.h" |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
45 } | 45 } |
46 | 46 |
47 } // anonymous namespace | 47 } // anonymous namespace |
48 | 48 |
49 class PermissionQueueController::PendingInfobarRequest { | 49 class PermissionQueueController::PendingInfobarRequest { |
50 public: | 50 public: |
51 PendingInfobarRequest(content::PermissionType type, | 51 PendingInfobarRequest(content::PermissionType type, |
52 const PermissionRequestID& id, | 52 const PermissionRequestID& id, |
53 const GURL& requesting_frame, | 53 const GURL& requesting_frame, |
54 const GURL& embedder, | 54 const GURL& embedder, |
| 55 bool user_gesture, |
55 Profile* profile, | 56 Profile* profile, |
56 const PermissionDecidedCallback& callback); | 57 const PermissionDecidedCallback& callback); |
57 ~PendingInfobarRequest(); | 58 ~PendingInfobarRequest(); |
58 | 59 |
59 bool IsForPair(const GURL& requesting_frame, | 60 bool IsForPair(const GURL& requesting_frame, |
60 const GURL& embedder) const; | 61 const GURL& embedder) const; |
61 | 62 |
62 const PermissionRequestID& id() const { return id_; } | 63 const PermissionRequestID& id() const { return id_; } |
63 const GURL& requesting_frame() const { return requesting_frame_; } | 64 const GURL& requesting_frame() const { return requesting_frame_; } |
64 bool has_infobar() const { return !!infobar_; } | 65 bool has_infobar() const { return !!infobar_; } |
65 infobars::InfoBar* infobar() { return infobar_; } | 66 infobars::InfoBar* infobar() { return infobar_; } |
66 | 67 |
67 void RunCallback(ContentSetting content_setting); | 68 void RunCallback(ContentSetting content_setting); |
68 void CreateInfoBar(PermissionQueueController* controller); | 69 void CreateInfoBar(PermissionQueueController* controller); |
69 | 70 |
70 private: | 71 private: |
71 content::PermissionType type_; | 72 content::PermissionType type_; |
72 PermissionRequestID id_; | 73 PermissionRequestID id_; |
73 GURL requesting_frame_; | 74 GURL requesting_frame_; |
74 GURL embedder_; | 75 GURL embedder_; |
| 76 bool user_gesture_; |
75 Profile* profile_; | 77 Profile* profile_; |
76 PermissionDecidedCallback callback_; | 78 PermissionDecidedCallback callback_; |
77 infobars::InfoBar* infobar_; | 79 infobars::InfoBar* infobar_; |
78 | 80 |
79 // Purposefully do not disable copying, as this is stored in STL containers. | 81 // Purposefully do not disable copying, as this is stored in STL containers. |
80 }; | 82 }; |
81 | 83 |
82 PermissionQueueController::PendingInfobarRequest::PendingInfobarRequest( | 84 PermissionQueueController::PendingInfobarRequest::PendingInfobarRequest( |
83 content::PermissionType type, | 85 content::PermissionType type, |
84 const PermissionRequestID& id, | 86 const PermissionRequestID& id, |
85 const GURL& requesting_frame, | 87 const GURL& requesting_frame, |
86 const GURL& embedder, | 88 const GURL& embedder, |
| 89 bool user_gesture, |
87 Profile* profile, | 90 Profile* profile, |
88 const PermissionDecidedCallback& callback) | 91 const PermissionDecidedCallback& callback) |
89 : type_(type), | 92 : type_(type), |
90 id_(id), | 93 id_(id), |
91 requesting_frame_(requesting_frame), | 94 requesting_frame_(requesting_frame), |
92 embedder_(embedder), | 95 embedder_(embedder), |
| 96 user_gesture_(user_gesture), |
93 profile_(profile), | 97 profile_(profile), |
94 callback_(callback), | 98 callback_(callback), |
95 infobar_(NULL) {} | 99 infobar_(NULL) {} |
96 | 100 |
97 PermissionQueueController::PendingInfobarRequest::~PendingInfobarRequest() { | 101 PermissionQueueController::PendingInfobarRequest::~PendingInfobarRequest() { |
98 } | 102 } |
99 | 103 |
100 bool PermissionQueueController::PendingInfobarRequest::IsForPair( | 104 bool PermissionQueueController::PendingInfobarRequest::IsForPair( |
101 const GURL& requesting_frame, | 105 const GURL& requesting_frame, |
102 const GURL& embedder) const { | 106 const GURL& embedder) const { |
103 return (requesting_frame_ == requesting_frame) && (embedder_ == embedder); | 107 return (requesting_frame_ == requesting_frame) && (embedder_ == embedder); |
104 } | 108 } |
105 | 109 |
106 void PermissionQueueController::PendingInfobarRequest::RunCallback( | 110 void PermissionQueueController::PendingInfobarRequest::RunCallback( |
107 ContentSetting content_setting) { | 111 ContentSetting content_setting) { |
108 callback_.Run(content_setting); | 112 callback_.Run(content_setting); |
109 } | 113 } |
110 | 114 |
111 void PermissionQueueController::PendingInfobarRequest::CreateInfoBar( | 115 void PermissionQueueController::PendingInfobarRequest::CreateInfoBar( |
112 PermissionQueueController* controller) { | 116 PermissionQueueController* controller) { |
113 // Controller can be Unretained because the lifetime of the infobar | 117 // Controller can be Unretained because the lifetime of the infobar |
114 // is tied to that of the queue controller. Before QueueController | 118 // is tied to that of the queue controller. Before QueueController |
115 // is destroyed, all requests will be cancelled and so all delegates | 119 // is destroyed, all requests will be cancelled and so all delegates |
116 // will be destroyed. | 120 // will be destroyed. |
117 PermissionInfobarDelegate::PermissionSetCallback callback = | 121 PermissionInfobarDelegate::PermissionSetCallback callback = base::Bind( |
118 base::Bind(&PermissionQueueController::OnPermissionSet, | 122 &PermissionQueueController::OnPermissionSet, base::Unretained(controller), |
119 base::Unretained(controller), | 123 id_, requesting_frame_, embedder_, user_gesture_); |
120 id_, | |
121 requesting_frame_, | |
122 embedder_); | |
123 switch (type_) { | 124 switch (type_) { |
124 case content::PermissionType::GEOLOCATION: | 125 case content::PermissionType::GEOLOCATION: |
125 infobar_ = GeolocationInfoBarDelegateAndroid::Create( | 126 infobar_ = GeolocationInfoBarDelegateAndroid::Create( |
126 GetInfoBarService(id_), requesting_frame_, profile_, callback); | 127 GetInfoBarService(id_), requesting_frame_, user_gesture_, profile_, |
| 128 callback); |
127 break; | 129 break; |
128 #if defined(ENABLE_NOTIFICATIONS) | 130 #if defined(ENABLE_NOTIFICATIONS) |
129 case content::PermissionType::NOTIFICATIONS: | 131 case content::PermissionType::NOTIFICATIONS: |
130 infobar_ = NotificationPermissionInfobarDelegate::Create( | 132 infobar_ = NotificationPermissionInfobarDelegate::Create( |
131 GetInfoBarService(id_), requesting_frame_, profile_, callback); | 133 GetInfoBarService(id_), requesting_frame_, user_gesture_, profile_, |
| 134 callback); |
132 break; | 135 break; |
133 #endif // ENABLE_NOTIFICATIONS | 136 #endif // ENABLE_NOTIFICATIONS |
134 case content::PermissionType::MIDI_SYSEX: | 137 case content::PermissionType::MIDI_SYSEX: |
135 infobar_ = MidiPermissionInfoBarDelegateAndroid::Create( | 138 infobar_ = MidiPermissionInfoBarDelegateAndroid::Create( |
136 GetInfoBarService(id_), requesting_frame_, profile_, callback); | 139 GetInfoBarService(id_), requesting_frame_, user_gesture_, profile_, |
| 140 callback); |
137 break; | 141 break; |
138 case content::PermissionType::PROTECTED_MEDIA_IDENTIFIER: | 142 case content::PermissionType::PROTECTED_MEDIA_IDENTIFIER: |
139 infobar_ = ProtectedMediaIdentifierInfoBarDelegateAndroid::Create( | 143 infobar_ = ProtectedMediaIdentifierInfoBarDelegateAndroid::Create( |
140 GetInfoBarService(id_), requesting_frame_, profile_, callback); | 144 GetInfoBarService(id_), requesting_frame_, user_gesture_, profile_, |
| 145 callback); |
141 break; | 146 break; |
142 default: | 147 default: |
143 NOTREACHED(); | 148 NOTREACHED(); |
144 break; | 149 break; |
145 } | 150 } |
146 } | 151 } |
147 | 152 |
148 PermissionQueueController::PermissionQueueController( | 153 PermissionQueueController::PermissionQueueController( |
149 Profile* profile, | 154 Profile* profile, |
150 content::PermissionType permission_type, | 155 content::PermissionType permission_type, |
151 ContentSettingsType content_settings_type) | 156 ContentSettingsType content_settings_type) |
152 : profile_(profile), | 157 : profile_(profile), |
153 permission_type_(permission_type), | 158 permission_type_(permission_type), |
154 content_settings_type_(content_settings_type), | 159 content_settings_type_(content_settings_type), |
155 in_shutdown_(false) {} | 160 in_shutdown_(false) {} |
156 | 161 |
157 PermissionQueueController::~PermissionQueueController() { | 162 PermissionQueueController::~PermissionQueueController() { |
158 // Cancel all outstanding requests. | 163 // Cancel all outstanding requests. |
159 in_shutdown_ = true; | 164 in_shutdown_ = true; |
160 while (!pending_infobar_requests_.empty()) | 165 while (!pending_infobar_requests_.empty()) |
161 CancelInfoBarRequest(pending_infobar_requests_.front().id()); | 166 CancelInfoBarRequest(pending_infobar_requests_.front().id()); |
162 } | 167 } |
163 | 168 |
164 void PermissionQueueController::CreateInfoBarRequest( | 169 void PermissionQueueController::CreateInfoBarRequest( |
165 const PermissionRequestID& id, | 170 const PermissionRequestID& id, |
166 const GURL& requesting_frame, | 171 const GURL& requesting_frame, |
167 const GURL& embedder, | 172 const GURL& embedder, |
| 173 bool user_gesture, |
168 const PermissionDecidedCallback& callback) { | 174 const PermissionDecidedCallback& callback) { |
169 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 175 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
170 | 176 |
171 if (requesting_frame.SchemeIs(content::kChromeUIScheme) || | 177 if (requesting_frame.SchemeIs(content::kChromeUIScheme) || |
172 embedder.SchemeIs(content::kChromeUIScheme)) | 178 embedder.SchemeIs(content::kChromeUIScheme)) |
173 return; | 179 return; |
174 | 180 |
175 pending_infobar_requests_.push_back(PendingInfobarRequest( | 181 pending_infobar_requests_.push_back( |
176 permission_type_, id, requesting_frame, embedder, profile_, callback)); | 182 PendingInfobarRequest(permission_type_, id, requesting_frame, embedder, |
| 183 user_gesture, profile_, callback)); |
177 if (!AlreadyShowingInfoBarForTab(id)) | 184 if (!AlreadyShowingInfoBarForTab(id)) |
178 ShowQueuedInfoBarForTab(id); | 185 ShowQueuedInfoBarForTab(id); |
179 } | 186 } |
180 | 187 |
181 void PermissionQueueController::CancelInfoBarRequest( | 188 void PermissionQueueController::CancelInfoBarRequest( |
182 const PermissionRequestID& id) { | 189 const PermissionRequestID& id) { |
183 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 190 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
184 | 191 |
185 for (PendingInfobarRequests::iterator i(pending_infobar_requests_.begin()); | 192 for (PendingInfobarRequests::iterator i(pending_infobar_requests_.begin()); |
186 i != pending_infobar_requests_.end(); ++i) { | 193 i != pending_infobar_requests_.end(); ++i) { |
187 if (id != i->id()) | 194 if (id != i->id()) |
188 continue; | 195 continue; |
189 | 196 |
190 InfoBarService* infobar_service = GetInfoBarService(id); | 197 InfoBarService* infobar_service = GetInfoBarService(id); |
191 if (infobar_service && i->has_infobar()) | 198 if (infobar_service && i->has_infobar()) |
192 infobar_service->RemoveInfoBar(i->infobar()); | 199 infobar_service->RemoveInfoBar(i->infobar()); |
193 else | 200 else |
194 pending_infobar_requests_.erase(i); | 201 pending_infobar_requests_.erase(i); |
195 return; | 202 return; |
196 } | 203 } |
197 } | 204 } |
198 | 205 |
199 void PermissionQueueController::OnPermissionSet( | 206 void PermissionQueueController::OnPermissionSet(const PermissionRequestID& id, |
200 const PermissionRequestID& id, | 207 const GURL& requesting_frame, |
201 const GURL& requesting_frame, | 208 const GURL& embedder, |
202 const GURL& embedder, | 209 bool user_gesture, |
203 bool update_content_setting, | 210 bool update_content_setting, |
204 bool allowed) { | 211 bool allowed) { |
205 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 212 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
206 | 213 |
207 // TODO(miguelg): move the permission persistence to | 214 // TODO(miguelg): move the permission persistence to |
208 // PermissionContextBase once all the types are moved there. | 215 // PermissionContextBase once all the types are moved there. |
209 // TODO(stefanocs): Pass the actual user_gesture value to PermissionUmaUtil. | |
210 if (update_content_setting) { | 216 if (update_content_setting) { |
211 UpdateContentSetting(requesting_frame, embedder, allowed); | 217 UpdateContentSetting(requesting_frame, embedder, allowed); |
212 if (allowed) | 218 if (allowed) |
213 PermissionUmaUtil::PermissionGranted(permission_type_, | 219 PermissionUmaUtil::PermissionGranted(permission_type_, user_gesture, |
214 false /* user_gesture */, | |
215 requesting_frame, profile_); | 220 requesting_frame, profile_); |
216 else | 221 else |
217 PermissionUmaUtil::PermissionDenied(permission_type_, | 222 PermissionUmaUtil::PermissionDenied(permission_type_, user_gesture, |
218 false /* user_gesture */, | |
219 requesting_frame, profile_); | 223 requesting_frame, profile_); |
220 } else { | 224 } else { |
221 PermissionUmaUtil::PermissionDismissed( | 225 PermissionUmaUtil::PermissionDismissed(permission_type_, user_gesture, |
222 permission_type_, false /* user_gesture */, requesting_frame, profile_); | 226 requesting_frame, profile_); |
223 } | 227 } |
224 | 228 |
225 // Cancel this request first, then notify listeners. TODO(pkasting): Why | 229 // Cancel this request first, then notify listeners. TODO(pkasting): Why |
226 // is this order important? | 230 // is this order important? |
227 PendingInfobarRequests requests_to_notify; | 231 PendingInfobarRequests requests_to_notify; |
228 PendingInfobarRequests infobars_to_remove; | 232 PendingInfobarRequests infobars_to_remove; |
229 std::vector<PendingInfobarRequests::iterator> pending_requests_to_remove; | 233 std::vector<PendingInfobarRequests::iterator> pending_requests_to_remove; |
230 for (PendingInfobarRequests::iterator i = pending_infobar_requests_.begin(); | 234 for (PendingInfobarRequests::iterator i = pending_infobar_requests_.begin(); |
231 i != pending_infobar_requests_.end(); ++i) { | 235 i != pending_infobar_requests_.end(); ++i) { |
232 if (!i->IsForPair(requesting_frame, embedder)) | 236 if (!i->IsForPair(requesting_frame, embedder)) |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
392 } | 396 } |
393 | 397 |
394 ContentSetting content_setting = | 398 ContentSetting content_setting = |
395 allowed ? CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK; | 399 allowed ? CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK; |
396 | 400 |
397 HostContentSettingsMapFactory::GetForProfile(profile_) | 401 HostContentSettingsMapFactory::GetForProfile(profile_) |
398 ->SetContentSettingDefaultScope( | 402 ->SetContentSettingDefaultScope( |
399 requesting_frame.GetOrigin(), embedder.GetOrigin(), | 403 requesting_frame.GetOrigin(), embedder.GetOrigin(), |
400 content_settings_type_, std::string(), content_setting); | 404 content_settings_type_, std::string(), content_setting); |
401 } | 405 } |
OLD | NEW |