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