OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/geolocation/geolocation_permission_context.h" | 5 #include "chrome/browser/geolocation/geolocation_permission_context.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "app/l10n_util.h" | 10 #include "app/l10n_util.h" |
11 #include "base/utf_string_conversions.h" | 11 #include "base/utf_string_conversions.h" |
(...skipping 15 matching lines...) Expand all Loading... |
27 #include "chrome/common/notification_source.h" | 27 #include "chrome/common/notification_source.h" |
28 #include "chrome/common/notification_type.h" | 28 #include "chrome/common/notification_type.h" |
29 #include "chrome/common/pref_names.h" | 29 #include "chrome/common/pref_names.h" |
30 #include "chrome/common/render_messages.h" | 30 #include "chrome/common/render_messages.h" |
31 #include "grit/generated_resources.h" | 31 #include "grit/generated_resources.h" |
32 #include "grit/locale_settings.h" | 32 #include "grit/locale_settings.h" |
33 #include "grit/theme_resources.h" | 33 #include "grit/theme_resources.h" |
34 #include "net/base/net_util.h" | 34 #include "net/base/net_util.h" |
35 #include "ui/base/resource/resource_bundle.h" | 35 #include "ui/base/resource/resource_bundle.h" |
36 | 36 |
37 namespace { | 37 // GeolocationInfoBarQueueController ------------------------------------------ |
38 | |
39 const char kGeolocationLearnMoreUrl[] = | |
40 #if defined(OS_CHROMEOS) | |
41 "http://www.google.com/support/chromeos/bin/answer.py?answer=142065"; | |
42 #else | |
43 "http://www.google.com/support/chrome/bin/answer.py?answer=142065"; | |
44 #endif | |
45 | |
46 } // namespace | |
47 | 38 |
48 // This class controls the geolocation infobar queue per profile, and it's an | 39 // This class controls the geolocation infobar queue per profile, and it's an |
49 // internal class to GeolocationPermissionContext. | 40 // internal class to GeolocationPermissionContext. |
50 // An alternate approach would be to have this queue per tab, and use | 41 // An alternate approach would be to have this queue per tab, and use |
51 // notifications to broadcast when permission is set / listen to notification to | 42 // notifications to broadcast when permission is set / listen to notification to |
52 // cancel pending requests. This may be specially useful if there are other | 43 // cancel pending requests. This may be specially useful if there are other |
53 // things listening for such notifications. | 44 // things listening for such notifications. |
54 // For the time being this class is self-contained and it doesn't seem pulling | 45 // For the time being this class is self-contained and it doesn't seem pulling |
55 // the notification infrastructure would simplify. | 46 // the notification infrastructure would simplify. |
56 class GeolocationInfoBarQueueController : NotificationObserver { | 47 class GeolocationInfoBarQueueController : NotificationObserver { |
57 public: | 48 public: |
58 GeolocationInfoBarQueueController( | 49 GeolocationInfoBarQueueController( |
59 GeolocationPermissionContext* geolocation_permission_context, | 50 GeolocationPermissionContext* geolocation_permission_context, |
60 Profile* profile); | 51 Profile* profile); |
61 ~GeolocationInfoBarQueueController(); | 52 ~GeolocationInfoBarQueueController(); |
62 | 53 |
63 // The InfoBar will be displayed immediately if the tab is not already | 54 // The InfoBar will be displayed immediately if the tab is not already |
64 // displaying one, otherwise it'll be queued. | 55 // displaying one, otherwise it'll be queued. |
65 void CreateInfoBarRequest( | 56 void CreateInfoBarRequest(int render_process_id, |
66 int render_process_id, int render_view_id, int bridge_id, | 57 int render_view_id, |
67 const GURL& requesting_frame, const GURL& emebedder); | 58 int bridge_id, |
| 59 const GURL& requesting_frame, |
| 60 const GURL& emebedder); |
68 | 61 |
69 // Cancels a specific infobar request. | 62 // Cancels a specific infobar request. |
70 void CancelInfoBarRequest( | 63 void CancelInfoBarRequest(int render_process_id, |
71 int render_process_id, int render_view_id, int bridge_id); | 64 int render_view_id, |
| 65 int bridge_id); |
72 | 66 |
73 // Called by the InfoBarDelegate to notify it's closed. It'll display a new | 67 // Called by the InfoBarDelegate to notify it's closed. It'll display a new |
74 // InfoBar if there's any request pending for this tab. | 68 // InfoBar if there's any request pending for this tab. |
75 void OnInfoBarClosed( | 69 void OnInfoBarClosed(int render_process_id, |
76 int render_process_id, int render_view_id, int bridge_id); | 70 int render_view_id, |
| 71 int bridge_id); |
77 | 72 |
78 // Called by the InfoBarDelegate to notify permission has been set. | 73 // Called by the InfoBarDelegate to notify permission has been set. |
79 // It'll notify and dismiss any other pending InfoBar request for the same | 74 // It'll notify and dismiss any other pending InfoBar request for the same |
80 // |requesting_frame| and embedder. | 75 // |requesting_frame| and embedder. |
81 void OnPermissionSet( | 76 void OnPermissionSet(int render_process_id, |
82 int render_process_id, int render_view_id, int bridge_id, | 77 int render_view_id, |
83 const GURL& requesting_frame, const GURL& embedder, bool allowed); | 78 int bridge_id, |
| 79 const GURL& requesting_frame, |
| 80 const GURL& embedder, |
| 81 bool allowed); |
84 | 82 |
85 // NotificationObserver | 83 // NotificationObserver |
86 virtual void Observe(NotificationType type, | 84 virtual void Observe(NotificationType type, |
87 const NotificationSource& source, | 85 const NotificationSource& source, |
88 const NotificationDetails& details); | 86 const NotificationDetails& details); |
89 | 87 |
90 private: | 88 private: |
91 struct PendingInfoBarRequest; | 89 struct PendingInfoBarRequest; |
92 typedef std::vector<PendingInfoBarRequest> PendingInfoBarRequests; | 90 typedef std::vector<PendingInfoBarRequest> PendingInfoBarRequests; |
93 | 91 |
94 // Shows the first pending infobar for this tab. | 92 // Shows the first pending infobar for this tab. |
95 void ShowQueuedInfoBar(int render_process_id, int render_view_id); | 93 void ShowQueuedInfoBar(int render_process_id, int render_view_id); |
96 | 94 |
97 // Cancels an InfoBar request and returns the next iterator position. | 95 // Cancels an InfoBar request and returns the next iterator position. |
98 std::vector<PendingInfoBarRequest>::iterator CancelInfoBarRequestInternal( | 96 std::vector<PendingInfoBarRequest>::iterator CancelInfoBarRequestInternal( |
99 std::vector<PendingInfoBarRequest>::iterator i); | 97 std::vector<PendingInfoBarRequest>::iterator i); |
100 | 98 |
101 NotificationRegistrar registrar_; | 99 NotificationRegistrar registrar_; |
102 | 100 |
103 GeolocationPermissionContext* const geolocation_permission_context_; | 101 GeolocationPermissionContext* const geolocation_permission_context_; |
104 Profile* const profile_; | 102 Profile* const profile_; |
105 // Contains all pending infobar requests. | 103 // Contains all pending infobar requests. |
106 PendingInfoBarRequests pending_infobar_requests_; | 104 PendingInfoBarRequests pending_infobar_requests_; |
107 }; | 105 }; |
108 | 106 |
109 namespace { | 107 namespace { |
110 | 108 |
111 // This is the delegate used to display the confirmation info bar. | 109 const char kGeolocationLearnMoreUrl[] = |
| 110 #if defined(OS_CHROMEOS) |
| 111 "http://www.google.com/support/chromeos/bin/answer.py?answer=142065"; |
| 112 #else |
| 113 "http://www.google.com/support/chrome/bin/answer.py?answer=142065"; |
| 114 #endif |
| 115 |
| 116 |
| 117 // GeolocationConfirmInfoBarDelegate ------------------------------------------ |
| 118 |
112 class GeolocationConfirmInfoBarDelegate : public ConfirmInfoBarDelegate { | 119 class GeolocationConfirmInfoBarDelegate : public ConfirmInfoBarDelegate { |
113 public: | 120 public: |
114 GeolocationConfirmInfoBarDelegate( | 121 GeolocationConfirmInfoBarDelegate( |
115 TabContents* tab_contents, GeolocationInfoBarQueueController* controller, | 122 TabContents* tab_contents, |
116 int render_process_id, int render_view_id, int bridge_id, | 123 GeolocationInfoBarQueueController* controller, |
| 124 int render_process_id, |
| 125 int render_view_id, |
| 126 int bridge_id, |
117 const GURL& requesting_frame_url, | 127 const GURL& requesting_frame_url, |
118 const std::string& display_languages) | 128 const std::string& display_languages); |
119 : ConfirmInfoBarDelegate(tab_contents), | |
120 tab_contents_(tab_contents), | |
121 controller_(controller), | |
122 render_process_id_(render_process_id), | |
123 render_view_id_(render_view_id), | |
124 bridge_id_(bridge_id), | |
125 requesting_frame_url_(requesting_frame_url), | |
126 display_languages_(display_languages) { | |
127 } | |
128 | |
129 // ConfirmInfoBarDelegate | |
130 virtual void InfoBarClosed() { | |
131 controller_->OnInfoBarClosed(render_process_id_, render_view_id_, | |
132 bridge_id_); | |
133 delete this; | |
134 } | |
135 virtual Type GetInfoBarType() { return PAGE_ACTION_TYPE; } | |
136 virtual bool Accept() { return OnPermissionSet(true); } | |
137 virtual bool Cancel() { return OnPermissionSet(false); } | |
138 virtual int GetButtons() const { return BUTTON_OK | BUTTON_CANCEL; } | |
139 virtual string16 GetButtonLabel(InfoBarButton button) const { | |
140 switch (button) { | |
141 case BUTTON_OK: | |
142 return l10n_util::GetStringUTF16(IDS_GEOLOCATION_ALLOW_BUTTON); | |
143 case BUTTON_CANCEL: | |
144 return l10n_util::GetStringUTF16(IDS_GEOLOCATION_DENY_BUTTON); | |
145 default: | |
146 // All buttons are labeled above. | |
147 NOTREACHED() << "Bad button id " << button; | |
148 return string16(); | |
149 } | |
150 } | |
151 virtual string16 GetMessageText() const { | |
152 return l10n_util::GetStringFUTF16( | |
153 IDS_GEOLOCATION_INFOBAR_QUESTION, | |
154 net::FormatUrl(requesting_frame_url_.GetOrigin(), display_languages_)); | |
155 } | |
156 virtual SkBitmap* GetIcon() const { | |
157 return ResourceBundle::GetSharedInstance().GetBitmapNamed( | |
158 IDR_GEOLOCATION_INFOBAR_ICON); | |
159 } | |
160 virtual string16 GetLinkText() { | |
161 return l10n_util::GetStringUTF16(IDS_LEARN_MORE); | |
162 } | |
163 virtual bool LinkClicked(WindowOpenDisposition disposition) { | |
164 GURL learn_more_url = | |
165 google_util::AppendGoogleLocaleParam(GURL(kGeolocationLearnMoreUrl)); | |
166 // Ignore the click disposition and always open in a new top level tab. | |
167 tab_contents_->OpenURL( | |
168 learn_more_url, GURL(), NEW_FOREGROUND_TAB, PageTransition::LINK); | |
169 return false; // Do not dismiss the info bar. | |
170 } | |
171 | 129 |
172 private: | 130 private: |
173 bool OnPermissionSet(bool confirm) { | 131 virtual ~GeolocationConfirmInfoBarDelegate(); |
174 controller_->OnPermissionSet( | 132 |
175 render_process_id_, render_view_id_, bridge_id_, requesting_frame_url_, | 133 // ConfirmInfoBarDelegate: |
176 tab_contents_->GetURL(), confirm); | 134 virtual void InfoBarClosed(); |
177 return true; | 135 virtual SkBitmap* GetIcon() const; |
178 } | 136 virtual Type GetInfoBarType() const; |
| 137 virtual string16 GetMessageText() const; |
| 138 virtual int GetButtons() const; |
| 139 virtual string16 GetButtonLabel(InfoBarButton button) const; |
| 140 virtual bool Accept(); |
| 141 virtual bool Cancel(); |
| 142 virtual string16 GetLinkText(); |
| 143 virtual bool LinkClicked(WindowOpenDisposition disposition); |
179 | 144 |
180 TabContents* tab_contents_; | 145 TabContents* tab_contents_; |
181 GeolocationInfoBarQueueController* controller_; | 146 GeolocationInfoBarQueueController* controller_; |
182 int render_process_id_; | 147 int render_process_id_; |
183 int render_view_id_; | 148 int render_view_id_; |
184 int bridge_id_; | 149 int bridge_id_; |
185 GURL requesting_frame_url_; | 150 GURL requesting_frame_url_; |
186 std::string display_languages_; | 151 std::string display_languages_; |
187 | 152 |
188 DISALLOW_IMPLICIT_CONSTRUCTORS(GeolocationConfirmInfoBarDelegate); | 153 DISALLOW_IMPLICIT_CONSTRUCTORS(GeolocationConfirmInfoBarDelegate); |
189 }; | 154 }; |
190 | 155 |
| 156 GeolocationConfirmInfoBarDelegate::GeolocationConfirmInfoBarDelegate( |
| 157 TabContents* tab_contents, |
| 158 GeolocationInfoBarQueueController* controller, |
| 159 int render_process_id, |
| 160 int render_view_id, |
| 161 int bridge_id, |
| 162 const GURL& requesting_frame_url, |
| 163 const std::string& display_languages) |
| 164 : ConfirmInfoBarDelegate(tab_contents), |
| 165 tab_contents_(tab_contents), |
| 166 controller_(controller), |
| 167 render_process_id_(render_process_id), |
| 168 render_view_id_(render_view_id), |
| 169 bridge_id_(bridge_id), |
| 170 requesting_frame_url_(requesting_frame_url), |
| 171 display_languages_(display_languages) { |
| 172 } |
| 173 |
| 174 GeolocationConfirmInfoBarDelegate::~GeolocationConfirmInfoBarDelegate() { |
| 175 } |
| 176 |
| 177 void GeolocationConfirmInfoBarDelegate::InfoBarClosed() { |
| 178 controller_->OnInfoBarClosed(render_process_id_, render_view_id_, |
| 179 bridge_id_); |
| 180 delete this; |
| 181 } |
| 182 |
| 183 SkBitmap* GeolocationConfirmInfoBarDelegate::GetIcon() const { |
| 184 return ResourceBundle::GetSharedInstance().GetBitmapNamed( |
| 185 IDR_GEOLOCATION_INFOBAR_ICON); |
| 186 } |
| 187 |
| 188 InfoBarDelegate::Type |
| 189 GeolocationConfirmInfoBarDelegate::GetInfoBarType() const { |
| 190 return PAGE_ACTION_TYPE; |
| 191 } |
| 192 |
| 193 string16 GeolocationConfirmInfoBarDelegate::GetMessageText() const { |
| 194 return l10n_util::GetStringFUTF16(IDS_GEOLOCATION_INFOBAR_QUESTION, |
| 195 net::FormatUrl(requesting_frame_url_.GetOrigin(), display_languages_)); |
| 196 } |
| 197 |
| 198 int GeolocationConfirmInfoBarDelegate::GetButtons() const { |
| 199 return BUTTON_OK | BUTTON_CANCEL; |
| 200 } |
| 201 |
| 202 string16 GeolocationConfirmInfoBarDelegate::GetButtonLabel( |
| 203 InfoBarButton button) const { |
| 204 return l10n_util::GetStringUTF16((button == BUTTON_OK) ? |
| 205 IDS_GEOLOCATION_ALLOW_BUTTON : IDS_GEOLOCATION_DENY_BUTTON); |
| 206 } |
| 207 |
| 208 bool GeolocationConfirmInfoBarDelegate::Accept() { |
| 209 controller_->OnPermissionSet(render_process_id_, render_view_id_, bridge_id_, |
| 210 requesting_frame_url_, tab_contents_->GetURL(), true); |
| 211 return true; |
| 212 } |
| 213 |
| 214 bool GeolocationConfirmInfoBarDelegate::Cancel() { |
| 215 controller_->OnPermissionSet(render_process_id_, render_view_id_, bridge_id_, |
| 216 requesting_frame_url_, tab_contents_->GetURL(), false); |
| 217 return true; |
| 218 } |
| 219 |
| 220 string16 GeolocationConfirmInfoBarDelegate::GetLinkText() { |
| 221 return l10n_util::GetStringUTF16(IDS_LEARN_MORE); |
| 222 } |
| 223 |
| 224 bool GeolocationConfirmInfoBarDelegate::LinkClicked( |
| 225 WindowOpenDisposition disposition) { |
| 226 // Ignore the click disposition and always open in a new top level tab. |
| 227 tab_contents_->OpenURL( |
| 228 google_util::AppendGoogleLocaleParam(GURL(kGeolocationLearnMoreUrl)), |
| 229 GURL(), NEW_FOREGROUND_TAB, PageTransition::LINK); |
| 230 return false; // Do not dismiss the info bar. |
| 231 } |
| 232 |
191 } // namespace | 233 } // namespace |
192 | 234 |
| 235 |
| 236 // GeolocationInfoBarQueueController ------------------------------------------ |
| 237 |
193 struct GeolocationInfoBarQueueController::PendingInfoBarRequest { | 238 struct GeolocationInfoBarQueueController::PendingInfoBarRequest { |
194 int render_process_id; | 239 int render_process_id; |
195 int render_view_id; | 240 int render_view_id; |
196 int bridge_id; | 241 int bridge_id; |
197 GURL requesting_frame; | 242 GURL requesting_frame; |
198 GURL embedder; | 243 GURL embedder; |
199 // If non-NULL, it's the current geolocation infobar for this tab. | 244 // If non-NULL, it's the current geolocation infobar for this tab. |
200 InfoBarDelegate* infobar_delegate; | 245 InfoBarDelegate* infobar_delegate; |
201 | 246 |
202 bool IsForTab(int p_render_process_id, int p_render_view_id) const { | 247 bool IsForTab(int p_render_process_id, int p_render_view_id) const { |
(...skipping 18 matching lines...) Expand all Loading... |
221 GeolocationPermissionContext* geolocation_permission_context, | 266 GeolocationPermissionContext* geolocation_permission_context, |
222 Profile* profile) | 267 Profile* profile) |
223 : geolocation_permission_context_(geolocation_permission_context), | 268 : geolocation_permission_context_(geolocation_permission_context), |
224 profile_(profile) { | 269 profile_(profile) { |
225 } | 270 } |
226 | 271 |
227 GeolocationInfoBarQueueController::~GeolocationInfoBarQueueController() { | 272 GeolocationInfoBarQueueController::~GeolocationInfoBarQueueController() { |
228 } | 273 } |
229 | 274 |
230 void GeolocationInfoBarQueueController::CreateInfoBarRequest( | 275 void GeolocationInfoBarQueueController::CreateInfoBarRequest( |
231 int render_process_id, int render_view_id, int bridge_id, | 276 int render_process_id, |
232 const GURL& requesting_frame, const GURL& embedder) { | 277 int render_view_id, |
| 278 int bridge_id, |
| 279 const GURL& requesting_frame, |
| 280 const GURL& embedder) { |
233 // This makes sure that no duplicates are added to | 281 // This makes sure that no duplicates are added to |
234 // |pending_infobar_requests_| as an artificial permission request may | 282 // |pending_infobar_requests_| as an artificial permission request may |
235 // already exist in the queue as per | 283 // already exist in the queue as per |
236 // GeolocationPermissionContext::StartUpdatingRequested | 284 // GeolocationPermissionContext::StartUpdatingRequested |
237 // See http://crbug.com/51899 for more details. | 285 // See http://crbug.com/51899 for more details. |
238 // TODO(joth): Once we have CLIENT_BASED_GEOLOCATION and | 286 // TODO(joth): Once we have CLIENT_BASED_GEOLOCATION and |
239 // WTF_USE_PREEMPT_GEOLOCATION_PERMISSION set in WebKit we should be able to | 287 // WTF_USE_PREEMPT_GEOLOCATION_PERMISSION set in WebKit we should be able to |
240 // just use a DCHECK to check if a duplicate is attempting to be added. | 288 // just use a DCHECK to check if a duplicate is attempting to be added. |
241 PendingInfoBarRequests::iterator i = pending_infobar_requests_.begin(); | 289 for (PendingInfoBarRequests::iterator i = pending_infobar_requests_.begin(); |
242 while (i != pending_infobar_requests_.end()) { | 290 i != pending_infobar_requests_.end(); ++i) { |
243 if (i->Equals(render_process_id, render_view_id, bridge_id)) { | 291 if (i->Equals(render_process_id, render_view_id, bridge_id)) { |
244 // The request already exists. | 292 // The request already exists. |
245 DCHECK(i->IsForPair(requesting_frame, embedder)); | 293 DCHECK(i->IsForPair(requesting_frame, embedder)); |
246 return; | 294 return; |
247 } | 295 } |
248 ++i; | |
249 } | 296 } |
250 PendingInfoBarRequest pending_infobar_request; | 297 PendingInfoBarRequest pending_infobar_request; |
251 pending_infobar_request.render_process_id = render_process_id; | 298 pending_infobar_request.render_process_id = render_process_id; |
252 pending_infobar_request.render_view_id = render_view_id; | 299 pending_infobar_request.render_view_id = render_view_id; |
253 pending_infobar_request.bridge_id = bridge_id; | 300 pending_infobar_request.bridge_id = bridge_id; |
254 pending_infobar_request.requesting_frame = requesting_frame; | 301 pending_infobar_request.requesting_frame = requesting_frame; |
255 pending_infobar_request.embedder = embedder; | 302 pending_infobar_request.embedder = embedder; |
256 pending_infobar_request.infobar_delegate = NULL; | 303 pending_infobar_request.infobar_delegate = NULL; |
257 pending_infobar_requests_.push_back(pending_infobar_request); | 304 pending_infobar_requests_.push_back(pending_infobar_request); |
258 ShowQueuedInfoBar(render_process_id, render_view_id); | 305 ShowQueuedInfoBar(render_process_id, render_view_id); |
259 } | 306 } |
260 | 307 |
261 void GeolocationInfoBarQueueController::CancelInfoBarRequest( | 308 void GeolocationInfoBarQueueController::CancelInfoBarRequest( |
262 int render_process_id, int render_view_id, int bridge_id) { | 309 int render_process_id, |
| 310 int render_view_id, |
| 311 int bridge_id) { |
263 for (PendingInfoBarRequests::iterator i = pending_infobar_requests_.begin(); | 312 for (PendingInfoBarRequests::iterator i = pending_infobar_requests_.begin(); |
264 i != pending_infobar_requests_.end(); ++i) { | 313 i != pending_infobar_requests_.end(); ++i) { |
265 if (i->Equals(render_process_id, render_view_id, bridge_id)) { | 314 if (i->Equals(render_process_id, render_view_id, bridge_id)) { |
266 CancelInfoBarRequestInternal(i); | 315 CancelInfoBarRequestInternal(i); |
267 break; | 316 return; |
268 } | 317 } |
269 } | 318 } |
270 } | 319 } |
271 | 320 |
272 void GeolocationInfoBarQueueController::OnInfoBarClosed( | 321 void GeolocationInfoBarQueueController::OnInfoBarClosed(int render_process_id, |
273 int render_process_id, int render_view_id, int bridge_id) { | 322 int render_view_id, |
| 323 int bridge_id) { |
274 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 324 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
275 for (PendingInfoBarRequests::iterator i = pending_infobar_requests_.begin(); | 325 for (PendingInfoBarRequests::iterator i = pending_infobar_requests_.begin(); |
276 i != pending_infobar_requests_.end(); ++i) { | 326 i != pending_infobar_requests_.end(); ++i) { |
277 if (i->Equals(render_process_id, render_view_id, bridge_id)) { | 327 if (i->Equals(render_process_id, render_view_id, bridge_id)) { |
278 pending_infobar_requests_.erase(i); | 328 pending_infobar_requests_.erase(i); |
279 break; | 329 break; |
280 } | 330 } |
281 } | 331 } |
282 ShowQueuedInfoBar(render_process_id, render_view_id); | 332 ShowQueuedInfoBar(render_process_id, render_view_id); |
283 } | 333 } |
284 | 334 |
285 void GeolocationInfoBarQueueController::OnPermissionSet( | 335 void GeolocationInfoBarQueueController::OnPermissionSet( |
286 int render_process_id, int render_view_id, int bridge_id, | 336 int render_process_id, |
287 const GURL& requesting_frame, const GURL& embedder, bool allowed) { | 337 int render_view_id, |
| 338 int bridge_id, |
| 339 const GURL& requesting_frame, |
| 340 const GURL& embedder, |
| 341 bool allowed) { |
288 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 342 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
289 // Persist the permission. | 343 // Persist the permission. |
290 ContentSetting content_setting = | 344 ContentSetting content_setting = |
291 allowed ? CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK; | 345 allowed ? CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK; |
292 profile_->GetGeolocationContentSettingsMap()->SetContentSetting( | 346 profile_->GetGeolocationContentSettingsMap()->SetContentSetting( |
293 requesting_frame.GetOrigin(), embedder.GetOrigin(), content_setting); | 347 requesting_frame.GetOrigin(), embedder.GetOrigin(), content_setting); |
294 | 348 |
295 // Now notify all pending requests that the permission has been set. | 349 // Now notify all pending requests that the permission has been set. |
296 for (PendingInfoBarRequests::iterator i = pending_infobar_requests_.begin(); | 350 for (PendingInfoBarRequests::iterator i = pending_infobar_requests_.begin(); |
297 i != pending_infobar_requests_.end();) { | 351 i != pending_infobar_requests_.end();) { |
298 if (i->IsForPair(requesting_frame, embedder)) { | 352 if (i->IsForPair(requesting_frame, embedder)) { |
299 // There was a pending request for the same [frame, embedder]. | 353 // There was a pending request for the same [frame, embedder]. |
300 if (i->Equals(render_process_id, render_view_id, bridge_id)) { | 354 if (i->Equals(render_process_id, render_view_id, bridge_id)) { |
301 // The request that set permission will be removed by TabContents | 355 // The request that set permission will be removed by TabContents |
302 // itself, that is, we should not try to cancel the infobar that has | 356 // itself, that is, we should not try to cancel the infobar that has |
303 // just notified us. | 357 // just notified us. |
304 i->infobar_delegate = NULL; | 358 i->infobar_delegate = NULL; |
305 } | 359 } |
306 // Cancel it first, and then notify the permission. | 360 // Cancel it first, and then notify the permission. |
307 // Note: if the pending request had an infobar, TabContents will | 361 // Note: if the pending request had an infobar, TabContents will |
308 // eventually close it and we will pump the queue via OnInfoBarClosed(). | 362 // eventually close it and we will pump the queue via OnInfoBarClosed(). |
309 PendingInfoBarRequest other_request = *i; | 363 PendingInfoBarRequest copied_request = *i; |
310 i = CancelInfoBarRequestInternal(i); | 364 i = CancelInfoBarRequestInternal(i); |
311 geolocation_permission_context_->NotifyPermissionSet( | 365 geolocation_permission_context_->NotifyPermissionSet( |
312 other_request.render_process_id, other_request.render_view_id, | 366 copied_request.render_process_id, copied_request.render_view_id, |
313 other_request.bridge_id, other_request.requesting_frame, allowed); | 367 copied_request.bridge_id, copied_request.requesting_frame, allowed); |
314 } else { | 368 } else { |
315 ++i; | 369 ++i; |
316 } | 370 } |
317 } | 371 } |
318 } | 372 } |
319 | 373 |
320 void GeolocationInfoBarQueueController::Observe( | 374 void GeolocationInfoBarQueueController::Observe( |
321 NotificationType type, const NotificationSource& source, | 375 NotificationType type, const NotificationSource& source, |
322 const NotificationDetails& details) { | 376 const NotificationDetails& details) { |
323 registrar_.Remove(this, NotificationType::TAB_CONTENTS_DESTROYED, | 377 registrar_.Remove(this, NotificationType::TAB_CONTENTS_DESTROYED, |
324 source); | 378 source); |
325 TabContents* tab_contents = Source<TabContents>(source).ptr(); | 379 TabContents* tab_contents = Source<TabContents>(source).ptr(); |
326 for (PendingInfoBarRequests::iterator i = pending_infobar_requests_.begin(); | 380 for (PendingInfoBarRequests::iterator i = pending_infobar_requests_.begin(); |
327 i != pending_infobar_requests_.end();) { | 381 i != pending_infobar_requests_.end();) { |
328 if (i->infobar_delegate == NULL && | 382 if (i->infobar_delegate == NULL && |
329 tab_contents == tab_util::GetTabContentsByID(i->render_process_id, | 383 tab_contents == tab_util::GetTabContentsByID(i->render_process_id, |
330 i->render_view_id)) { | 384 i->render_view_id)) { |
331 i = pending_infobar_requests_.erase(i); | 385 i = pending_infobar_requests_.erase(i); |
332 } else { | 386 } else { |
333 ++i; | 387 ++i; |
334 } | 388 } |
335 } | 389 } |
336 } | 390 } |
337 | 391 |
338 void GeolocationInfoBarQueueController::ShowQueuedInfoBar( | 392 void GeolocationInfoBarQueueController::ShowQueuedInfoBar(int render_process_id, |
339 int render_process_id, int render_view_id) { | 393 int render_view_id) { |
340 TabContents* tab_contents = | 394 TabContents* tab_contents = |
341 tab_util::GetTabContentsByID(render_process_id, render_view_id); | 395 tab_util::GetTabContentsByID(render_process_id, render_view_id); |
342 for (PendingInfoBarRequests::iterator i = pending_infobar_requests_.begin(); | 396 for (PendingInfoBarRequests::iterator i = pending_infobar_requests_.begin(); |
343 i != pending_infobar_requests_.end();) { | 397 i != pending_infobar_requests_.end();) { |
344 if (!i->IsForTab(render_process_id, render_view_id)) { | 398 if (!i->IsForTab(render_process_id, render_view_id)) { |
345 ++i; | 399 ++i; |
346 continue; | 400 continue; |
347 } | 401 } |
348 if (!tab_contents) { | 402 if (!tab_contents) { |
349 i = pending_infobar_requests_.erase(i); | 403 i = pending_infobar_requests_.erase(i); |
350 continue; | 404 continue; |
351 } | 405 } |
352 // Check if already displayed. | 406 // Check if already displayed. |
353 if (i->infobar_delegate) | 407 if (i->infobar_delegate) |
354 break; | 408 break; |
355 if (!registrar_.IsRegistered( | 409 if (!registrar_.IsRegistered(this, NotificationType::TAB_CONTENTS_DESTROYED, |
356 this, NotificationType::TAB_CONTENTS_DESTROYED, | |
357 Source<TabContents>(tab_contents))) { | 410 Source<TabContents>(tab_contents))) { |
358 registrar_.Add( | 411 registrar_.Add(this, NotificationType::TAB_CONTENTS_DESTROYED, |
359 this, NotificationType::TAB_CONTENTS_DESTROYED, | |
360 Source<TabContents>(tab_contents)); | 412 Source<TabContents>(tab_contents)); |
361 } | 413 } |
362 i->infobar_delegate = new GeolocationConfirmInfoBarDelegate( | 414 i->infobar_delegate = new GeolocationConfirmInfoBarDelegate(tab_contents, |
363 tab_contents, this, | 415 this, render_process_id, render_view_id, i->bridge_id, |
364 render_process_id, render_view_id, | 416 i->requesting_frame, |
365 i->bridge_id, i->requesting_frame, | |
366 profile_->GetPrefs()->GetString(prefs::kAcceptLanguages)); | 417 profile_->GetPrefs()->GetString(prefs::kAcceptLanguages)); |
367 tab_contents->AddInfoBar(i->infobar_delegate); | 418 tab_contents->AddInfoBar(i->infobar_delegate); |
368 break; | 419 break; |
369 } | 420 } |
370 } | 421 } |
371 | 422 |
372 std::vector<GeolocationInfoBarQueueController::PendingInfoBarRequest>::iterator | 423 std::vector<GeolocationInfoBarQueueController::PendingInfoBarRequest>::iterator |
373 GeolocationInfoBarQueueController::CancelInfoBarRequestInternal( | 424 GeolocationInfoBarQueueController::CancelInfoBarRequestInternal( |
374 std::vector<PendingInfoBarRequest>::iterator i) { | 425 std::vector<PendingInfoBarRequest>::iterator i) { |
375 TabContents* tab_contents = | 426 TabContents* tab_contents = |
376 tab_util::GetTabContentsByID(i->render_process_id, i->render_view_id); | 427 tab_util::GetTabContentsByID(i->render_process_id, i->render_view_id); |
377 if (tab_contents && i->infobar_delegate) { | 428 if (tab_contents && i->infobar_delegate) { |
378 // TabContents will destroy the InfoBar, which will remove from our vector | 429 // TabContents will destroy the InfoBar, which will remove from our vector |
379 // asynchronously. | 430 // asynchronously. |
380 tab_contents->RemoveInfoBar(i->infobar_delegate); | 431 tab_contents->RemoveInfoBar(i->infobar_delegate); |
381 return ++i; | 432 return ++i; |
382 } else { | 433 } else { |
383 // Remove it directly from the pending vector. | 434 // Remove it directly from the pending vector. |
384 return pending_infobar_requests_.erase(i); | 435 return pending_infobar_requests_.erase(i); |
385 } | 436 } |
386 } | 437 } |
387 | 438 |
388 GeolocationPermissionContext::GeolocationPermissionContext( | 439 GeolocationPermissionContext::GeolocationPermissionContext( |
389 Profile* profile) | 440 Profile* profile) |
390 : profile_(profile), | 441 : profile_(profile), |
391 ALLOW_THIS_IN_INITIALIZER_LIST( | 442 ALLOW_THIS_IN_INITIALIZER_LIST(geolocation_infobar_queue_controller_( |
392 geolocation_infobar_queue_controller_( | 443 new GeolocationInfoBarQueueController(this, profile))) { |
393 new GeolocationInfoBarQueueController(this, profile))) { | |
394 } | 444 } |
395 | 445 |
396 GeolocationPermissionContext::~GeolocationPermissionContext() { | 446 GeolocationPermissionContext::~GeolocationPermissionContext() { |
397 } | 447 } |
398 | 448 |
399 void GeolocationPermissionContext::RequestGeolocationPermission( | 449 void GeolocationPermissionContext::RequestGeolocationPermission( |
400 int render_process_id, int render_view_id, int bridge_id, | 450 int render_process_id, int render_view_id, int bridge_id, |
401 const GURL& requesting_frame) { | 451 const GURL& requesting_frame) { |
402 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { | 452 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { |
403 BrowserThread::PostTask( | 453 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, NewRunnableMethod( |
404 BrowserThread::UI, FROM_HERE, | 454 this, &GeolocationPermissionContext::RequestGeolocationPermission, |
405 NewRunnableMethod(this, | 455 render_process_id, render_view_id, bridge_id, requesting_frame)); |
406 &GeolocationPermissionContext::RequestGeolocationPermission, | |
407 render_process_id, render_view_id, bridge_id, requesting_frame)); | |
408 return; | 456 return; |
409 } | 457 } |
410 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 458 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
411 | 459 |
412 ExtensionService* extensions = profile_->GetExtensionService(); | 460 ExtensionService* extensions = profile_->GetExtensionService(); |
413 if (extensions) { | 461 if (extensions) { |
414 const Extension* ext = extensions->GetExtensionByURL(requesting_frame); | 462 const Extension* ext = extensions->GetExtensionByURL(requesting_frame); |
415 if (!ext) | 463 if (!ext) |
416 ext = extensions->GetExtensionByWebExtent(requesting_frame); | 464 ext = extensions->GetExtensionByWebExtent(requesting_frame); |
417 if (ext && ext->HasApiPermission(Extension::kGeolocationPermission)) { | 465 if (ext && ext->HasApiPermission(Extension::kGeolocationPermission)) { |
418 ExtensionProcessManager* epm = profile_->GetExtensionProcessManager(); | 466 ExtensionProcessManager* epm = profile_->GetExtensionProcessManager(); |
419 RenderProcessHost* process = epm->GetExtensionProcess(requesting_frame); | 467 RenderProcessHost* process = epm->GetExtensionProcess(requesting_frame); |
420 if (process && process->id() == render_process_id) { | 468 if (process && process->id() == render_process_id) { |
421 NotifyPermissionSet(render_process_id, render_view_id, bridge_id, | 469 NotifyPermissionSet(render_process_id, render_view_id, bridge_id, |
422 requesting_frame, true); | 470 requesting_frame, true); |
423 return; | 471 return; |
424 } | 472 } |
425 } | 473 } |
426 } | 474 } |
427 | 475 |
428 TabContents* tab_contents = | 476 TabContents* tab_contents = |
429 tab_util::GetTabContentsByID(render_process_id, render_view_id); | 477 tab_util::GetTabContentsByID(render_process_id, render_view_id); |
430 if (!tab_contents) { | 478 if (!tab_contents) { |
431 // The tab may have gone away, or the request may not be from a tab at all. | 479 // The tab may have gone away, or the request may not be from a tab at all. |
432 LOG(WARNING) << "Attempt to use geolocation tabless renderer: " | 480 LOG(WARNING) << "Attempt to use geolocation tabless renderer: " |
433 << render_process_id << "," << render_view_id << "," << bridge_id | 481 << render_process_id << "," << render_view_id << "," |
434 << " (can't prompt user without a visible tab)"; | 482 << bridge_id << " (can't prompt user without a visible tab)"; |
435 NotifyPermissionSet(render_process_id, render_view_id, bridge_id, | 483 NotifyPermissionSet(render_process_id, render_view_id, bridge_id, |
436 requesting_frame, false); | 484 requesting_frame, false); |
437 return; | 485 return; |
438 } | 486 } |
439 | 487 |
440 GURL embedder = tab_contents->GetURL(); | 488 GURL embedder = tab_contents->GetURL(); |
441 if (!requesting_frame.is_valid() || !embedder.is_valid()) { | 489 if (!requesting_frame.is_valid() || !embedder.is_valid()) { |
442 LOG(WARNING) << "Attempt to use geolocation from an invalid URL: " | 490 LOG(WARNING) << "Attempt to use geolocation from an invalid URL: " |
443 << requesting_frame << "," << embedder | 491 << requesting_frame << "," << embedder |
444 << " (geolocation is not supported in popups)"; | 492 << " (geolocation is not supported in popups)"; |
445 NotifyPermissionSet(render_process_id, render_view_id, bridge_id, | 493 NotifyPermissionSet(render_process_id, render_view_id, bridge_id, |
446 requesting_frame, false); | 494 requesting_frame, false); |
447 return; | 495 return; |
448 } | 496 } |
449 | 497 |
450 ContentSetting content_setting = | 498 ContentSetting content_setting = |
451 profile_->GetGeolocationContentSettingsMap()->GetContentSetting( | 499 profile_->GetGeolocationContentSettingsMap()->GetContentSetting( |
452 requesting_frame, embedder); | 500 requesting_frame, embedder); |
453 if (content_setting == CONTENT_SETTING_BLOCK) { | 501 if (content_setting == CONTENT_SETTING_BLOCK) { |
454 NotifyPermissionSet(render_process_id, render_view_id, bridge_id, | 502 NotifyPermissionSet(render_process_id, render_view_id, bridge_id, |
455 requesting_frame, false); | 503 requesting_frame, false); |
456 } else if (content_setting == CONTENT_SETTING_ALLOW) { | 504 } else if (content_setting == CONTENT_SETTING_ALLOW) { |
457 NotifyPermissionSet(render_process_id, render_view_id, bridge_id, | 505 NotifyPermissionSet(render_process_id, render_view_id, bridge_id, |
458 requesting_frame, true); | 506 requesting_frame, true); |
459 } else { // setting == ask. Prompt the user. | 507 } else { // setting == ask. Prompt the user. |
460 geolocation_infobar_queue_controller_->CreateInfoBarRequest( | 508 geolocation_infobar_queue_controller_->CreateInfoBarRequest( |
461 render_process_id, render_view_id, bridge_id, requesting_frame, | 509 render_process_id, render_view_id, bridge_id, requesting_frame, |
462 embedder); | 510 embedder); |
463 } | 511 } |
464 } | 512 } |
465 | 513 |
466 void GeolocationPermissionContext::CancelGeolocationPermissionRequest( | 514 void GeolocationPermissionContext::CancelGeolocationPermissionRequest( |
467 int render_process_id, int render_view_id, int bridge_id, | 515 int render_process_id, |
| 516 int render_view_id, |
| 517 int bridge_id, |
468 const GURL& requesting_frame) { | 518 const GURL& requesting_frame) { |
469 CancelPendingInfoBarRequest(render_process_id, render_view_id, bridge_id); | 519 CancelPendingInfoBarRequest(render_process_id, render_view_id, bridge_id); |
470 } | 520 } |
471 | 521 |
472 void GeolocationPermissionContext::NotifyPermissionSet( | 522 void GeolocationPermissionContext::NotifyPermissionSet( |
473 int render_process_id, int render_view_id, int bridge_id, | 523 int render_process_id, |
474 const GURL& requesting_frame, bool allowed) { | 524 int render_view_id, |
| 525 int bridge_id, |
| 526 const GURL& requesting_frame, |
| 527 bool allowed) { |
475 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 528 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
476 | 529 |
477 TabContents* tab_contents = | 530 TabContents* tab_contents = |
478 tab_util::GetTabContentsByID(render_process_id, render_view_id); | 531 tab_util::GetTabContentsByID(render_process_id, render_view_id); |
479 | 532 |
480 // TabContents may have gone away (or not exists for extension). | 533 // TabContents may have gone away (or not exists for extension). |
481 if (tab_contents) { | 534 if (tab_contents) { |
482 TabSpecificContentSettings* content_settings = | 535 TabSpecificContentSettings* content_settings = |
483 tab_contents->GetTabSpecificContentSettings(); | 536 tab_contents->GetTabSpecificContentSettings(); |
484 content_settings->OnGeolocationPermissionSet(requesting_frame.GetOrigin(), | 537 content_settings->OnGeolocationPermissionSet(requesting_frame.GetOrigin(), |
485 allowed); | 538 allowed); |
486 } | 539 } |
487 | 540 |
488 CallRenderViewHost( | 541 CallRenderViewHost(render_process_id, render_view_id, &RenderViewHost::Send, |
489 render_process_id, render_view_id, | |
490 &RenderViewHost::Send, | |
491 new ViewMsg_Geolocation_PermissionSet(render_view_id, bridge_id, | 542 new ViewMsg_Geolocation_PermissionSet(render_view_id, bridge_id, |
492 allowed)); | 543 allowed)); |
493 if (allowed) { | 544 if (allowed) { |
494 BrowserThread::PostTask( | 545 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, NewRunnableMethod( |
495 BrowserThread::IO, FROM_HERE, | 546 this, &GeolocationPermissionContext::NotifyArbitratorPermissionGranted, |
496 NewRunnableMethod(this, | 547 requesting_frame)); |
497 &GeolocationPermissionContext::NotifyArbitratorPermissionGranted, | |
498 requesting_frame)); | |
499 } | 548 } |
500 } | 549 } |
501 | 550 |
502 void GeolocationPermissionContext::NotifyArbitratorPermissionGranted( | 551 void GeolocationPermissionContext::NotifyArbitratorPermissionGranted( |
503 const GURL& requesting_frame) { | 552 const GURL& requesting_frame) { |
504 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 553 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
505 GeolocationProvider::GetInstance()->OnPermissionGranted(requesting_frame); | 554 GeolocationProvider::GetInstance()->OnPermissionGranted(requesting_frame); |
506 } | 555 } |
507 | 556 |
508 void GeolocationPermissionContext::CancelPendingInfoBarRequest( | 557 void GeolocationPermissionContext::CancelPendingInfoBarRequest( |
509 int render_process_id, int render_view_id, int bridge_id) { | 558 int render_process_id, |
| 559 int render_view_id, |
| 560 int bridge_id) { |
510 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { | 561 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { |
511 BrowserThread::PostTask( | 562 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, NewRunnableMethod( |
512 BrowserThread::UI, FROM_HERE, | 563 this, &GeolocationPermissionContext::CancelPendingInfoBarRequest, |
513 NewRunnableMethod(this, | 564 render_process_id, render_view_id, bridge_id)); |
514 &GeolocationPermissionContext::CancelPendingInfoBarRequest, | |
515 render_process_id, render_view_id, bridge_id)); | |
516 return; | 565 return; |
517 } | 566 } |
518 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 567 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
519 geolocation_infobar_queue_controller_->CancelInfoBarRequest( | 568 geolocation_infobar_queue_controller_->CancelInfoBarRequest(render_process_id, |
520 render_process_id, render_view_id, bridge_id); | 569 render_view_id, bridge_id); |
521 } | 570 } |
OLD | NEW |