| 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 |