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