| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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_infobar_queue_controller.h" | 5 #include "chrome/browser/geolocation/geolocation_infobar_queue_controller.h" |
| 6 | 6 |
| 7 #include "chrome/browser/content_settings/host_content_settings_map.h" | 7 #include "chrome/browser/content_settings/host_content_settings_map.h" |
| 8 #include "chrome/browser/geolocation/geolocation_confirm_infobar_delegate.h" | 8 #include "chrome/browser/geolocation/geolocation_confirm_infobar_delegate.h" |
| 9 #include "chrome/browser/geolocation/geolocation_confirm_infobar_delegate_factor
y.h" | 9 #include "chrome/browser/geolocation/geolocation_confirm_infobar_delegate_factor
y.h" |
| 10 #include "chrome/browser/infobars/infobar.h" | 10 #include "chrome/browser/infobars/infobar.h" |
| 11 #include "chrome/browser/infobars/infobar_tab_helper.h" | 11 #include "chrome/browser/infobars/infobar_tab_helper.h" |
| 12 #include "chrome/browser/prefs/pref_service.h" | 12 #include "chrome/browser/prefs/pref_service.h" |
| 13 #include "chrome/browser/profiles/profile.h" | 13 #include "chrome/browser/profiles/profile.h" |
| 14 #include "chrome/browser/tab_contents/tab_util.h" | 14 #include "chrome/browser/tab_contents/tab_util.h" |
| 15 #include "chrome/common/chrome_notification_types.h" | 15 #include "chrome/common/chrome_notification_types.h" |
| 16 #include "chrome/common/content_settings.h" | 16 #include "chrome/common/content_settings.h" |
| 17 #include "chrome/common/pref_names.h" | 17 #include "chrome/common/pref_names.h" |
| 18 #include "content/public/browser/browser_thread.h" | 18 #include "content/public/browser/browser_thread.h" |
| 19 #include "content/public/browser/notification_details.h" | 19 #include "content/public/browser/notification_details.h" |
| 20 #include "content/public/browser/notification_source.h" | 20 #include "content/public/browser/notification_source.h" |
| 21 #include "content/public/browser/notification_types.h" | 21 #include "content/public/browser/notification_types.h" |
| 22 #include "content/public/browser/web_contents.h" | 22 #include "content/public/browser/web_contents.h" |
| 23 | 23 |
| 24 using content::BrowserThread; | 24 |
| 25 using content::WebContents; | 25 // Utilities ------------------------------------------------------------------ |
| 26 |
| 27 namespace { |
| 28 |
| 29 InfoBarTabHelper* GetInfoBarHelper(const GeolocationPermissionRequestID& id) { |
| 30 content::WebContents* web_contents = |
| 31 tab_util::GetWebContentsByID(id.render_process_id(), id.render_view_id()); |
| 32 return web_contents ? InfoBarTabHelper::FromWebContents(web_contents) : NULL; |
| 33 } |
| 34 |
| 35 } |
| 36 |
| 26 | 37 |
| 27 // GeolocationInfoBarQueueController::PendingInfoBarRequest ------------------- | 38 // GeolocationInfoBarQueueController::PendingInfoBarRequest ------------------- |
| 28 | 39 |
| 29 struct GeolocationInfoBarQueueController::PendingInfoBarRequest { | 40 class GeolocationInfoBarQueueController::PendingInfoBarRequest { |
| 30 public: | 41 public: |
| 31 PendingInfoBarRequest(int render_process_id, | 42 PendingInfoBarRequest(const GeolocationPermissionRequestID& id, |
| 32 int render_view_id, | |
| 33 int bridge_id, | |
| 34 const GURL& requesting_frame, | 43 const GURL& requesting_frame, |
| 35 const GURL& embedder, | 44 const GURL& embedder, |
| 36 PermissionDecidedCallback callback); | 45 PermissionDecidedCallback callback); |
| 46 ~PendingInfoBarRequest(); |
| 37 | 47 |
| 38 bool IsForTab(int p_render_process_id, int p_render_view_id) const; | 48 bool IsForPair(const GURL& requesting_frame, |
| 39 bool IsForPair(const GURL& p_requesting_frame, | 49 const GURL& embedder) const; |
| 40 const GURL& p_embedder) const; | |
| 41 bool Equals(int p_render_process_id, | |
| 42 int p_render_view_id, | |
| 43 int p_bridge_id) const; | |
| 44 | 50 |
| 45 int render_process_id; | 51 const GeolocationPermissionRequestID& id() const { return id_; } |
| 46 int render_view_id; | 52 const GURL& requesting_frame() const { return requesting_frame_; } |
| 47 int bridge_id; | 53 bool has_infobar_delegate() const { return !!infobar_delegate_; } |
| 48 GURL requesting_frame; | 54 GeolocationConfirmInfoBarDelegate* infobar_delegate() { |
| 49 GURL embedder; | 55 return infobar_delegate_; |
| 50 PermissionDecidedCallback callback; | 56 } |
| 51 GeolocationConfirmInfoBarDelegate* infobar_delegate; | 57 |
| 58 void RunCallback(bool allowed); |
| 59 void CreateInfoBarDelegate(GeolocationInfoBarQueueController* controller, |
| 60 const std::string& display_languages); |
| 61 |
| 62 private: |
| 63 GeolocationPermissionRequestID id_; |
| 64 GURL requesting_frame_; |
| 65 GURL embedder_; |
| 66 PermissionDecidedCallback callback_; |
| 67 GeolocationConfirmInfoBarDelegate* infobar_delegate_; |
| 68 |
| 69 // Purposefully do not disable copying, as this is stored in STL containers. |
| 52 }; | 70 }; |
| 53 | 71 |
| 54 GeolocationInfoBarQueueController::PendingInfoBarRequest::PendingInfoBarRequest( | 72 GeolocationInfoBarQueueController::PendingInfoBarRequest::PendingInfoBarRequest( |
| 55 int render_process_id, | 73 const GeolocationPermissionRequestID& id, |
| 56 int render_view_id, | |
| 57 int bridge_id, | |
| 58 const GURL& requesting_frame, | 74 const GURL& requesting_frame, |
| 59 const GURL& embedder, | 75 const GURL& embedder, |
| 60 PermissionDecidedCallback callback) | 76 PermissionDecidedCallback callback) |
| 61 : render_process_id(render_process_id), | 77 : id_(id), |
| 62 render_view_id(render_view_id), | 78 requesting_frame_(requesting_frame), |
| 63 bridge_id(bridge_id), | 79 embedder_(embedder), |
| 64 requesting_frame(requesting_frame), | 80 callback_(callback), |
| 65 embedder(embedder), | 81 infobar_delegate_(NULL) { |
| 66 callback(callback), | |
| 67 infobar_delegate(NULL) { | |
| 68 } | 82 } |
| 69 | 83 |
| 70 bool GeolocationInfoBarQueueController::PendingInfoBarRequest::IsForTab( | 84 GeolocationInfoBarQueueController::PendingInfoBarRequest:: |
| 71 int p_render_process_id, | 85 ~PendingInfoBarRequest() { |
| 72 int p_render_view_id) const { | |
| 73 return (render_process_id == p_render_process_id) && | |
| 74 (render_view_id == p_render_view_id); | |
| 75 } | 86 } |
| 76 | 87 |
| 77 bool GeolocationInfoBarQueueController::PendingInfoBarRequest::IsForPair( | 88 bool GeolocationInfoBarQueueController::PendingInfoBarRequest::IsForPair( |
| 78 const GURL& p_requesting_frame, | 89 const GURL& requesting_frame, |
| 79 const GURL& p_embedder) const { | 90 const GURL& embedder) const { |
| 80 return (requesting_frame == p_requesting_frame) && (embedder == p_embedder); | 91 return (requesting_frame_ == requesting_frame) && (embedder_ == embedder); |
| 81 } | 92 } |
| 82 | 93 |
| 83 bool GeolocationInfoBarQueueController::PendingInfoBarRequest::Equals( | 94 void GeolocationInfoBarQueueController::PendingInfoBarRequest::RunCallback( |
| 84 int p_render_process_id, | 95 bool allowed) { |
| 85 int p_render_view_id, | 96 callback_.Run(allowed); |
| 86 int p_bridge_id) const { | 97 } |
| 87 return IsForTab(p_render_process_id, p_render_view_id) && | 98 |
| 88 (bridge_id == p_bridge_id); | 99 void GeolocationInfoBarQueueController::PendingInfoBarRequest:: |
| 100 CreateInfoBarDelegate(GeolocationInfoBarQueueController* controller, |
| 101 const std::string& display_languages) { |
| 102 infobar_delegate_ = GeolocationConfirmInfoBarDelegateFactory::Create( |
| 103 GetInfoBarHelper(id_), controller, id_, requesting_frame_, |
| 104 display_languages); |
| 105 |
| 89 } | 106 } |
| 90 | 107 |
| 91 | 108 |
| 92 // GeolocationInfoBarQueueController::RequestEquals --------------------------- | |
| 93 | |
| 94 // Useful predicate for checking PendingInfoBarRequest equality. | |
| 95 class GeolocationInfoBarQueueController::RequestEquals | |
| 96 : public std::unary_function<PendingInfoBarRequest, bool> { | |
| 97 public: | |
| 98 RequestEquals(int render_process_id, int render_view_id, int bridge_id); | |
| 99 | |
| 100 bool operator()(const PendingInfoBarRequest& request) const; | |
| 101 | |
| 102 private: | |
| 103 int render_process_id_; | |
| 104 int render_view_id_; | |
| 105 int bridge_id_; | |
| 106 }; | |
| 107 | |
| 108 GeolocationInfoBarQueueController::RequestEquals::RequestEquals( | |
| 109 int render_process_id, | |
| 110 int render_view_id, | |
| 111 int bridge_id) | |
| 112 : render_process_id_(render_process_id), | |
| 113 render_view_id_(render_view_id), | |
| 114 bridge_id_(bridge_id) { | |
| 115 } | |
| 116 | |
| 117 bool GeolocationInfoBarQueueController::RequestEquals::operator()( | |
| 118 const PendingInfoBarRequest& request) const { | |
| 119 return request.Equals(render_process_id_, render_view_id_, bridge_id_); | |
| 120 } | |
| 121 | |
| 122 // GeolocationInfoBarQueueController ------------------------------------------ | 109 // GeolocationInfoBarQueueController ------------------------------------------ |
| 123 | 110 |
| 124 GeolocationInfoBarQueueController::GeolocationInfoBarQueueController( | 111 GeolocationInfoBarQueueController::GeolocationInfoBarQueueController( |
| 125 Profile* profile) | 112 Profile* profile) |
| 126 : profile_(profile) { | 113 : profile_(profile) { |
| 127 } | 114 } |
| 128 | 115 |
| 129 GeolocationInfoBarQueueController::~GeolocationInfoBarQueueController() { | 116 GeolocationInfoBarQueueController::~GeolocationInfoBarQueueController() { |
| 130 } | 117 } |
| 131 | 118 |
| 132 void GeolocationInfoBarQueueController::CreateInfoBarRequest( | 119 void GeolocationInfoBarQueueController::CreateInfoBarRequest( |
| 133 int render_process_id, | 120 const GeolocationPermissionRequestID& id, |
| 134 int render_view_id, | |
| 135 int bridge_id, | |
| 136 const GURL& requesting_frame, | 121 const GURL& requesting_frame, |
| 137 const GURL& embedder, | 122 const GURL& embedder, |
| 138 PermissionDecidedCallback callback) { | 123 PermissionDecidedCallback callback) { |
| 139 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 124 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
| 140 | 125 |
| 141 // We shouldn't get duplicate requests. | 126 // We shouldn't get duplicate requests. |
| 142 DCHECK(std::find_if(pending_infobar_requests_.begin(), | 127 for (PendingInfoBarRequests::const_iterator i( |
| 143 pending_infobar_requests_.end(), | 128 pending_infobar_requests_.begin()); |
| 144 RequestEquals(render_process_id, render_view_id, bridge_id)) == | 129 i != pending_infobar_requests_.end(); ++i) |
| 145 pending_infobar_requests_.end()); | 130 DCHECK(!i->id().Equals(id)); |
| 146 | 131 |
| 147 InfoBarTabHelper* helper = GetInfoBarHelper(render_process_id, | 132 pending_infobar_requests_.push_back(PendingInfoBarRequest( |
| 148 render_view_id); | 133 id, requesting_frame, embedder, callback)); |
| 149 if (!helper) { | 134 if (!AlreadyShowingInfoBarForTab(id)) |
| 150 // We won't be able to create any infobars, shortcut and remove any pending | 135 ShowQueuedInfoBarForTab(id); |
| 151 // requests. | |
| 152 ClearPendingInfoBarRequestsForTab(render_process_id, render_view_id); | |
| 153 return; | |
| 154 } | |
| 155 pending_infobar_requests_.push_back(PendingInfoBarRequest(render_process_id, | |
| 156 render_view_id, bridge_id, requesting_frame, embedder, callback)); | |
| 157 if (!AlreadyShowingInfoBar(render_process_id, render_view_id)) | |
| 158 ShowQueuedInfoBar(render_process_id, render_view_id, helper); | |
| 159 } | 136 } |
| 160 | 137 |
| 161 void GeolocationInfoBarQueueController::CancelInfoBarRequest( | 138 void GeolocationInfoBarQueueController::CancelInfoBarRequest( |
| 162 int render_process_id, | 139 const GeolocationPermissionRequestID& id) { |
| 163 int render_view_id, | 140 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
| 164 int bridge_id) { | |
| 165 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 166 | 141 |
| 167 PendingInfoBarRequests::iterator i = std::find_if( | 142 for (PendingInfoBarRequests::iterator i(pending_infobar_requests_.begin()); |
| 168 pending_infobar_requests_.begin(), pending_infobar_requests_.end(), | 143 i != pending_infobar_requests_.end(); ++i) { |
| 169 RequestEquals(render_process_id, render_view_id, bridge_id)); | 144 if (i->id().Equals(id)) { |
| 170 // TODO(pkasting): Can this conditional become a DCHECK()? | 145 if (i->has_infobar_delegate()) |
| 171 if (i == pending_infobar_requests_.end()) | 146 GetInfoBarHelper(id)->RemoveInfoBar(i->infobar_delegate()); |
| 172 return; | 147 else |
| 173 InfoBarDelegate* delegate = i->infobar_delegate; | 148 pending_infobar_requests_.erase(i); |
| 174 if (!delegate) { | 149 return; |
| 175 pending_infobar_requests_.erase(i); | 150 } |
| 176 return; | |
| 177 } | 151 } |
| 178 InfoBarTabHelper* helper = GetInfoBarHelper(render_process_id, | |
| 179 render_view_id); | |
| 180 helper->RemoveInfoBar(delegate); | |
| 181 } | 152 } |
| 182 | 153 |
| 183 void GeolocationInfoBarQueueController::OnPermissionSet( | 154 void GeolocationInfoBarQueueController::OnPermissionSet( |
| 184 int render_process_id, | 155 const GeolocationPermissionRequestID& id, |
| 185 int render_view_id, | |
| 186 int bridge_id, | |
| 187 const GURL& requesting_frame, | 156 const GURL& requesting_frame, |
| 188 const GURL& embedder, | 157 const GURL& embedder, |
| 189 bool update_content_setting, | 158 bool update_content_setting, |
| 190 bool allowed) { | 159 bool allowed) { |
| 191 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 160 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
| 161 |
| 192 if (update_content_setting) { | 162 if (update_content_setting) { |
| 193 ContentSetting content_setting = | 163 ContentSetting content_setting = |
| 194 allowed ? CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK; | 164 allowed ? CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK; |
| 195 profile_->GetHostContentSettingsMap()->SetContentSetting( | 165 profile_->GetHostContentSettingsMap()->SetContentSetting( |
| 196 ContentSettingsPattern::FromURLNoWildcard(requesting_frame.GetOrigin()), | 166 ContentSettingsPattern::FromURLNoWildcard(requesting_frame.GetOrigin()), |
| 197 ContentSettingsPattern::FromURLNoWildcard(embedder.GetOrigin()), | 167 ContentSettingsPattern::FromURLNoWildcard(embedder.GetOrigin()), |
| 198 CONTENT_SETTINGS_TYPE_GEOLOCATION, | 168 CONTENT_SETTINGS_TYPE_GEOLOCATION, |
| 199 std::string(), | 169 std::string(), |
| 200 content_setting); | 170 content_setting); |
| 201 } | 171 } |
| 172 |
| 202 // Cancel this request first, then notify listeners. TODO(pkasting): Why | 173 // Cancel this request first, then notify listeners. TODO(pkasting): Why |
| 203 // is this order important? | 174 // is this order important? |
| 204 PendingInfoBarRequests requests_to_notify; | 175 PendingInfoBarRequests requests_to_notify; |
| 205 PendingInfoBarRequests infobars_to_remove; | 176 PendingInfoBarRequests infobars_to_remove; |
| 206 for (PendingInfoBarRequests::iterator i = pending_infobar_requests_.begin(); | 177 for (PendingInfoBarRequests::iterator i = pending_infobar_requests_.begin(); |
| 207 i != pending_infobar_requests_.end(); ) { | 178 i != pending_infobar_requests_.end(); ) { |
| 208 if (i->IsForPair(requesting_frame, embedder)) { | 179 if (i->IsForPair(requesting_frame, embedder)) { |
| 209 requests_to_notify.push_back(*i); | 180 requests_to_notify.push_back(*i); |
| 210 if (i->Equals(render_process_id, render_view_id, bridge_id)) { | 181 if (i->id().Equals(id)) { |
| 211 // The delegate that called us is i, and it's currently in either | 182 // The delegate that called us is i, and it's currently in either |
| 212 // Accept() or Cancel(). This means that the owning InfoBar will call | 183 // Accept() or Cancel(). This means that the owning InfoBar will call |
| 213 // RemoveInfoBar() later on, and that will trigger a notification we're | 184 // RemoveInfoBar() later on, and that will trigger a notification we're |
| 214 // observing. | 185 // observing. |
| 215 ++i; | 186 ++i; |
| 216 } else if (i->infobar_delegate) { | 187 } else if (i->has_infobar_delegate()) { |
| 217 // This InfoBar is for the same frame/embedder pair, but in a different | 188 // This InfoBar is for the same frame/embedder pair, but in a different |
| 218 // tab. We should remove it now that we've got an answer for it. | 189 // tab. We should remove it now that we've got an answer for it. |
| 219 infobars_to_remove.push_back(*i); | 190 infobars_to_remove.push_back(*i); |
| 220 ++i; | 191 ++i; |
| 221 } else { | 192 } else { |
| 222 // We haven't created an InfoBar yet, just remove the pending request. | 193 // We haven't created an InfoBar yet, just remove the pending request. |
| 223 i = pending_infobar_requests_.erase(i); | 194 i = pending_infobar_requests_.erase(i); |
| 224 } | 195 } |
| 225 } else { | 196 } else { |
| 226 ++i; | 197 ++i; |
| 227 } | 198 } |
| 228 } | 199 } |
| 229 | 200 |
| 230 // Remove all InfoBars for the same |requesting_frame| and |embedder|. | 201 // Remove all InfoBars for the same |requesting_frame| and |embedder|. |
| 231 for (PendingInfoBarRequests::iterator i = infobars_to_remove.begin(); | 202 for (PendingInfoBarRequests::iterator i = infobars_to_remove.begin(); |
| 232 i != infobars_to_remove.end(); ++i ) { | 203 i != infobars_to_remove.end(); ++i) |
| 233 InfoBarTabHelper* helper = GetInfoBarHelper(i->render_process_id, | 204 GetInfoBarHelper(i->id())->RemoveInfoBar(i->infobar_delegate()); |
| 234 i->render_view_id); | |
| 235 helper->RemoveInfoBar(i->infobar_delegate); | |
| 236 } | |
| 237 | 205 |
| 238 // Send out the permission notifications. | 206 // Send out the permission notifications. |
| 239 for (PendingInfoBarRequests::iterator i = requests_to_notify.begin(); | 207 for (PendingInfoBarRequests::iterator i = requests_to_notify.begin(); |
| 240 i != requests_to_notify.end(); ++i ) { | 208 i != requests_to_notify.end(); ++i) |
| 241 i->callback.Run(allowed); | 209 i->RunCallback(allowed); |
| 242 } | |
| 243 } | 210 } |
| 244 | 211 |
| 245 void GeolocationInfoBarQueueController::Observe( | 212 void GeolocationInfoBarQueueController::Observe( |
| 246 int type, | 213 int type, |
| 247 const content::NotificationSource& source, | 214 const content::NotificationSource& source, |
| 248 const content::NotificationDetails& details) { | 215 const content::NotificationDetails& details) { |
| 249 DCHECK_EQ(chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED, type); | 216 DCHECK_EQ(chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED, type); |
| 250 // We will receive this notification for all infobar closures, so we need to | 217 // We will receive this notification for all infobar closures, so we need to |
| 251 // check whether this is the geolocation infobar we're tracking. Note that the | 218 // check whether this is the geolocation infobar we're tracking. Note that the |
| 252 // InfoBarContainer (if any) may have received this notification before us and | 219 // InfoBarContainer (if any) may have received this notification before us and |
| 253 // caused the delegate to be deleted, so it's not safe to dereference the | 220 // caused the delegate to be deleted, so it's not safe to dereference the |
| 254 // contents of the delegate. The address of the delegate, however, is OK to | 221 // contents of the delegate. The address of the delegate, however, is OK to |
| 255 // use to find the PendingInfoBarRequest to remove because | 222 // use to find the PendingInfoBarRequest to remove because |
| 256 // pending_infobar_requests_ will not have received any new entries between | 223 // pending_infobar_requests_ will not have received any new entries between |
| 257 // the NotificationService's call to InfoBarContainer::Observe and this | 224 // the NotificationService's call to InfoBarContainer::Observe and this |
| 258 // method. | 225 // method. |
| 259 InfoBarDelegate* delegate = | 226 InfoBarDelegate* delegate = |
| 260 content::Details<InfoBarRemovedDetails>(details)->first; | 227 content::Details<InfoBarRemovedDetails>(details)->first; |
| 261 for (PendingInfoBarRequests::iterator i = pending_infobar_requests_.begin(); | 228 for (PendingInfoBarRequests::iterator i = pending_infobar_requests_.begin(); |
| 262 i != pending_infobar_requests_.end(); ++i) { | 229 i != pending_infobar_requests_.end(); ++i) { |
| 263 GeolocationConfirmInfoBarDelegate* confirm_delegate = i->infobar_delegate; | 230 GeolocationConfirmInfoBarDelegate* confirm_delegate = i->infobar_delegate(); |
| 264 if (confirm_delegate == delegate) { | 231 if (confirm_delegate == delegate) { |
| 265 InfoBarTabHelper* helper = | 232 GeolocationPermissionRequestID id(i->id()); |
| 266 content::Source<InfoBarTabHelper>(source).ptr(); | |
| 267 int render_process_id = i->render_process_id; | |
| 268 int render_view_id = i->render_view_id; | |
| 269 pending_infobar_requests_.erase(i); | 233 pending_infobar_requests_.erase(i); |
| 270 ShowQueuedInfoBar(render_process_id, render_view_id, helper); | 234 ShowQueuedInfoBarForTab(id); |
| 271 return; | 235 return; |
| 272 } | 236 } |
| 273 } | 237 } |
| 274 } | 238 } |
| 275 | 239 |
| 276 GeolocationConfirmInfoBarDelegate* | 240 bool GeolocationInfoBarQueueController::AlreadyShowingInfoBarForTab( |
| 277 GeolocationInfoBarQueueController::CreateInfoBarDelegate( | 241 const GeolocationPermissionRequestID& id) const { |
| 278 InfoBarTabHelper* infobar_helper, | 242 for (PendingInfoBarRequests::const_iterator i( |
| 279 GeolocationInfoBarQueueController* controller, | 243 pending_infobar_requests_.begin()); |
| 280 int render_process_id, | 244 i != pending_infobar_requests_.end(); ++i) { |
| 281 int render_view_id, | 245 if (i->id().IsForSameTabAs(id) && i->has_infobar_delegate()) |
| 282 int bridge_id, | 246 return true; |
| 283 const GURL& requesting_frame_url, | 247 } |
| 284 const std::string& display_languages) { | 248 return false; |
| 285 return GeolocationConfirmInfoBarDelegateFactory::Create( | |
| 286 infobar_helper, controller, render_process_id, render_view_id, bridge_id, | |
| 287 requesting_frame_url, display_languages); | |
| 288 } | 249 } |
| 289 | 250 |
| 290 void GeolocationInfoBarQueueController::ShowQueuedInfoBar( | 251 void GeolocationInfoBarQueueController::ShowQueuedInfoBarForTab( |
| 291 int render_process_id, | 252 const GeolocationPermissionRequestID& id) { |
| 292 int render_view_id, | 253 DCHECK(!AlreadyShowingInfoBarForTab(id)); |
| 293 InfoBarTabHelper* helper) { | 254 |
| 294 DCHECK(helper); | 255 InfoBarTabHelper* helper = GetInfoBarHelper(id); |
| 295 DCHECK(!AlreadyShowingInfoBar(render_process_id, render_view_id)); | 256 if (!helper) { |
| 257 // We can get here for example during tab shutdown, when the |
| 258 // InfoBarTabHelper is removing all existing infobars, thus calling back to |
| 259 // Observe(). In this case the helper still exists, and is supplied as the |
| 260 // source of the notification we observed, but is no longer accessible from |
| 261 // its WebContents. In this case we should just go ahead and cancel further |
| 262 // infobars for this tab instead of trying to access the helper. |
| 263 ClearPendingInfoBarRequestsForTab(id); |
| 264 return; |
| 265 } |
| 266 |
| 296 for (PendingInfoBarRequests::iterator i = pending_infobar_requests_.begin(); | 267 for (PendingInfoBarRequests::iterator i = pending_infobar_requests_.begin(); |
| 297 i != pending_infobar_requests_.end(); ++i) { | 268 i != pending_infobar_requests_.end(); ++i) { |
| 298 if (i->IsForTab(render_process_id, render_view_id) && | 269 if (i->id().IsForSameTabAs(id) && !i->has_infobar_delegate()) { |
| 299 !i->infobar_delegate) { | |
| 300 RegisterForInfoBarNotifications(helper); | 270 RegisterForInfoBarNotifications(helper); |
| 301 i->infobar_delegate = CreateInfoBarDelegate( | 271 i->CreateInfoBarDelegate( |
| 302 helper, this, render_process_id, | 272 this, profile_->GetPrefs()->GetString(prefs::kAcceptLanguages)); |
| 303 render_view_id, i->bridge_id, i->requesting_frame, | 273 helper->AddInfoBar(i->infobar_delegate()); |
| 304 profile_->GetPrefs()->GetString(prefs::kAcceptLanguages)); | |
| 305 helper->AddInfoBar(i->infobar_delegate); | |
| 306 return; | 274 return; |
| 307 } | 275 } |
| 308 } | 276 } |
| 277 |
| 309 UnregisterForInfoBarNotifications(helper); | 278 UnregisterForInfoBarNotifications(helper); |
| 310 } | 279 } |
| 311 | 280 |
| 312 void GeolocationInfoBarQueueController::ClearPendingInfoBarRequestsForTab( | 281 void GeolocationInfoBarQueueController::ClearPendingInfoBarRequestsForTab( |
| 313 int render_process_id, | 282 const GeolocationPermissionRequestID& id) { |
| 314 int render_view_id) { | |
| 315 for (PendingInfoBarRequests::iterator i = pending_infobar_requests_.begin(); | 283 for (PendingInfoBarRequests::iterator i = pending_infobar_requests_.begin(); |
| 316 i != pending_infobar_requests_.end(); ) { | 284 i != pending_infobar_requests_.end(); ) { |
| 317 if (i->IsForTab(render_process_id, render_view_id)) | 285 if (i->id().IsForSameTabAs(id)) |
| 318 i = pending_infobar_requests_.erase(i); | 286 i = pending_infobar_requests_.erase(i); |
| 319 else | 287 else |
| 320 ++i; | 288 ++i; |
| 321 } | 289 } |
| 322 } | 290 } |
| 323 | 291 |
| 324 InfoBarTabHelper* GeolocationInfoBarQueueController::GetInfoBarHelper( | |
| 325 int render_process_id, | |
| 326 int render_view_id) { | |
| 327 WebContents* web_contents = | |
| 328 tab_util::GetWebContentsByID(render_process_id, render_view_id); | |
| 329 return web_contents ? InfoBarTabHelper::FromWebContents(web_contents) : NULL; | |
| 330 } | |
| 331 | |
| 332 bool GeolocationInfoBarQueueController::AlreadyShowingInfoBar( | |
| 333 int render_process_id, | |
| 334 int render_view_id) { | |
| 335 for (PendingInfoBarRequests::iterator i = pending_infobar_requests_.begin(); | |
| 336 i != pending_infobar_requests_.end(); ++i) { | |
| 337 if (i->IsForTab(render_process_id, render_view_id) && i->infobar_delegate) | |
| 338 return true; | |
| 339 } | |
| 340 return false; | |
| 341 } | |
| 342 | |
| 343 void GeolocationInfoBarQueueController::RegisterForInfoBarNotifications( | 292 void GeolocationInfoBarQueueController::RegisterForInfoBarNotifications( |
| 344 InfoBarTabHelper* helper) { | 293 InfoBarTabHelper* helper) { |
| 345 if (!registrar_.IsRegistered( | 294 if (!registrar_.IsRegistered( |
| 346 this, chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED, | 295 this, chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED, |
| 347 content::Source<InfoBarTabHelper>(helper))) { | 296 content::Source<InfoBarTabHelper>(helper))) { |
| 348 registrar_.Add(this, | 297 registrar_.Add(this, |
| 349 chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED, | 298 chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED, |
| 350 content::Source<InfoBarTabHelper>(helper)); | 299 content::Source<InfoBarTabHelper>(helper)); |
| 351 } | 300 } |
| 352 } | 301 } |
| 353 | 302 |
| 354 void GeolocationInfoBarQueueController::UnregisterForInfoBarNotifications( | 303 void GeolocationInfoBarQueueController::UnregisterForInfoBarNotifications( |
| 355 InfoBarTabHelper* helper) { | 304 InfoBarTabHelper* helper) { |
| 356 if (registrar_.IsRegistered( | 305 if (registrar_.IsRegistered( |
| 357 this, chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED, | 306 this, chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED, |
| 358 content::Source<InfoBarTabHelper>(helper))) { | 307 content::Source<InfoBarTabHelper>(helper))) { |
| 359 registrar_.Remove(this, | 308 registrar_.Remove(this, |
| 360 chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED, | 309 chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED, |
| 361 content::Source<InfoBarTabHelper>(helper)); | 310 content::Source<InfoBarTabHelper>(helper)); |
| 362 } | 311 } |
| 363 } | 312 } |
| OLD | NEW |