Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(469)

Unified Diff: chrome/browser/geolocation/geolocation_infobar_queue_controller.cc

Issue 11269002: Introduce GeolocationPermissionRequestID, a wrapper struct to contain the (render process ID, rende… (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 8 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/geolocation/geolocation_infobar_queue_controller.cc
===================================================================
--- chrome/browser/geolocation/geolocation_infobar_queue_controller.cc (revision 163741)
+++ chrome/browser/geolocation/geolocation_infobar_queue_controller.cc (working copy)
@@ -21,103 +21,90 @@
#include "content/public/browser/notification_types.h"
#include "content/public/browser/web_contents.h"
-using content::BrowserThread;
-using content::WebContents;
+// Utilities ------------------------------------------------------------------
+
+namespace {
+
+InfoBarTabHelper* GetInfoBarHelper(const GeolocationPermissionRequestID& id) {
+ content::WebContents* web_contents =
+ tab_util::GetWebContentsByID(id.render_process_id(), id.render_view_id());
+ return web_contents ? InfoBarTabHelper::FromWebContents(web_contents) : NULL;
+}
+
+}
+
+
// GeolocationInfoBarQueueController::PendingInfoBarRequest -------------------
-struct GeolocationInfoBarQueueController::PendingInfoBarRequest {
+class GeolocationInfoBarQueueController::PendingInfoBarRequest {
public:
- PendingInfoBarRequest(int render_process_id,
- int render_view_id,
- int bridge_id,
+ PendingInfoBarRequest(const GeolocationPermissionRequestID& id,
const GURL& requesting_frame,
const GURL& embedder,
PermissionDecidedCallback callback);
+ ~PendingInfoBarRequest();
- bool IsForTab(int p_render_process_id, int p_render_view_id) const;
- bool IsForPair(const GURL& p_requesting_frame,
- const GURL& p_embedder) const;
- bool Equals(int p_render_process_id,
- int p_render_view_id,
- int p_bridge_id) const;
+ bool IsForPair(const GURL& requesting_frame,
+ const GURL& embedder) const;
- int render_process_id;
- int render_view_id;
- int bridge_id;
- GURL requesting_frame;
- GURL embedder;
- PermissionDecidedCallback callback;
- GeolocationConfirmInfoBarDelegate* infobar_delegate;
+ const GeolocationPermissionRequestID& id() const { return id_; }
+ const GURL& requesting_frame() const { return requesting_frame_; }
+ bool has_infobar_delegate() const { return !!infobar_delegate_; }
+ GeolocationConfirmInfoBarDelegate* infobar_delegate() {
+ return infobar_delegate_;
+ }
+
+ void RunCallback(bool allowed);
+ void CreateInfoBarDelegate(GeolocationInfoBarQueueController* controller,
+ const std::string& display_languages);
+
+ private:
+ GeolocationPermissionRequestID id_;
+ GURL requesting_frame_;
+ GURL embedder_;
+ PermissionDecidedCallback callback_;
+ GeolocationConfirmInfoBarDelegate* infobar_delegate_;
+
+ // Purposefully do not disable copying, as this is stored in STL containers.
};
GeolocationInfoBarQueueController::PendingInfoBarRequest::PendingInfoBarRequest(
- int render_process_id,
- int render_view_id,
- int bridge_id,
+ const GeolocationPermissionRequestID& id,
const GURL& requesting_frame,
const GURL& embedder,
PermissionDecidedCallback callback)
- : render_process_id(render_process_id),
- render_view_id(render_view_id),
- bridge_id(bridge_id),
- requesting_frame(requesting_frame),
- embedder(embedder),
- callback(callback),
- infobar_delegate(NULL) {
+ : id_(id),
+ requesting_frame_(requesting_frame),
+ embedder_(embedder),
+ callback_(callback),
+ infobar_delegate_(NULL) {
}
-bool GeolocationInfoBarQueueController::PendingInfoBarRequest::IsForTab(
- int p_render_process_id,
- int p_render_view_id) const {
- return (render_process_id == p_render_process_id) &&
- (render_view_id == p_render_view_id);
+GeolocationInfoBarQueueController::PendingInfoBarRequest::
+ ~PendingInfoBarRequest() {
}
bool GeolocationInfoBarQueueController::PendingInfoBarRequest::IsForPair(
- const GURL& p_requesting_frame,
- const GURL& p_embedder) const {
- return (requesting_frame == p_requesting_frame) && (embedder == p_embedder);
+ const GURL& requesting_frame,
+ const GURL& embedder) const {
+ return (requesting_frame_ == requesting_frame) && (embedder_ == embedder);
}
-bool GeolocationInfoBarQueueController::PendingInfoBarRequest::Equals(
- int p_render_process_id,
- int p_render_view_id,
- int p_bridge_id) const {
- return IsForTab(p_render_process_id, p_render_view_id) &&
- (bridge_id == p_bridge_id);
+void GeolocationInfoBarQueueController::PendingInfoBarRequest::RunCallback(
+ bool allowed) {
+ callback_.Run(allowed);
}
+void GeolocationInfoBarQueueController::PendingInfoBarRequest::
+ CreateInfoBarDelegate(GeolocationInfoBarQueueController* controller,
+ const std::string& display_languages) {
+ infobar_delegate_ = GeolocationConfirmInfoBarDelegateFactory::Create(
+ GetInfoBarHelper(id_), controller, id_, requesting_frame_,
+ display_languages);
-// GeolocationInfoBarQueueController::RequestEquals ---------------------------
-
-// Useful predicate for checking PendingInfoBarRequest equality.
-class GeolocationInfoBarQueueController::RequestEquals
- : public std::unary_function<PendingInfoBarRequest, bool> {
- public:
- RequestEquals(int render_process_id, int render_view_id, int bridge_id);
-
- bool operator()(const PendingInfoBarRequest& request) const;
-
- private:
- int render_process_id_;
- int render_view_id_;
- int bridge_id_;
-};
-
-GeolocationInfoBarQueueController::RequestEquals::RequestEquals(
- int render_process_id,
- int render_view_id,
- int bridge_id)
- : render_process_id_(render_process_id),
- render_view_id_(render_view_id),
- bridge_id_(bridge_id) {
}
-bool GeolocationInfoBarQueueController::RequestEquals::operator()(
- const PendingInfoBarRequest& request) const {
- return request.Equals(render_process_id_, render_view_id_, bridge_id_);
-}
// GeolocationInfoBarQueueController ------------------------------------------
@@ -130,65 +117,48 @@
}
void GeolocationInfoBarQueueController::CreateInfoBarRequest(
- int render_process_id,
- int render_view_id,
- int bridge_id,
+ const GeolocationPermissionRequestID& id,
const GURL& requesting_frame,
const GURL& embedder,
PermissionDecidedCallback callback) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
// We shouldn't get duplicate requests.
- DCHECK(std::find_if(pending_infobar_requests_.begin(),
- pending_infobar_requests_.end(),
- RequestEquals(render_process_id, render_view_id, bridge_id)) ==
- pending_infobar_requests_.end());
+ for (PendingInfoBarRequests::const_iterator i(
+ pending_infobar_requests_.begin());
+ i != pending_infobar_requests_.end(); ++i)
+ DCHECK(!i->id().Equals(id));
- InfoBarTabHelper* helper = GetInfoBarHelper(render_process_id,
- render_view_id);
- if (!helper) {
- // We won't be able to create any infobars, shortcut and remove any pending
- // requests.
- ClearPendingInfoBarRequestsForTab(render_process_id, render_view_id);
- return;
- }
- pending_infobar_requests_.push_back(PendingInfoBarRequest(render_process_id,
- render_view_id, bridge_id, requesting_frame, embedder, callback));
- if (!AlreadyShowingInfoBar(render_process_id, render_view_id))
- ShowQueuedInfoBar(render_process_id, render_view_id, helper);
+ pending_infobar_requests_.push_back(PendingInfoBarRequest(
+ id, requesting_frame, embedder, callback));
+ if (!AlreadyShowingInfoBarForTab(id))
+ ShowQueuedInfoBarForTab(id);
}
void GeolocationInfoBarQueueController::CancelInfoBarRequest(
- int render_process_id,
- int render_view_id,
- int bridge_id) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ const GeolocationPermissionRequestID& id) {
+ DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
- PendingInfoBarRequests::iterator i = std::find_if(
- pending_infobar_requests_.begin(), pending_infobar_requests_.end(),
- RequestEquals(render_process_id, render_view_id, bridge_id));
- // TODO(pkasting): Can this conditional become a DCHECK()?
- if (i == pending_infobar_requests_.end())
- return;
- InfoBarDelegate* delegate = i->infobar_delegate;
- if (!delegate) {
- pending_infobar_requests_.erase(i);
- return;
+ for (PendingInfoBarRequests::iterator i(pending_infobar_requests_.begin());
+ i != pending_infobar_requests_.end(); ++i) {
+ if (i->id().Equals(id)) {
+ if (i->has_infobar_delegate())
+ GetInfoBarHelper(id)->RemoveInfoBar(i->infobar_delegate());
+ else
+ pending_infobar_requests_.erase(i);
+ return;
+ }
}
- InfoBarTabHelper* helper = GetInfoBarHelper(render_process_id,
- render_view_id);
- helper->RemoveInfoBar(delegate);
}
void GeolocationInfoBarQueueController::OnPermissionSet(
- int render_process_id,
- int render_view_id,
- int bridge_id,
+ const GeolocationPermissionRequestID& id,
const GURL& requesting_frame,
const GURL& embedder,
bool update_content_setting,
bool allowed) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+
if (update_content_setting) {
ContentSetting content_setting =
allowed ? CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK;
@@ -199,6 +169,7 @@
std::string(),
content_setting);
}
+
// Cancel this request first, then notify listeners. TODO(pkasting): Why
// is this order important?
PendingInfoBarRequests requests_to_notify;
@@ -207,13 +178,13 @@
i != pending_infobar_requests_.end(); ) {
if (i->IsForPair(requesting_frame, embedder)) {
requests_to_notify.push_back(*i);
- if (i->Equals(render_process_id, render_view_id, bridge_id)) {
+ if (i->id().Equals(id)) {
// The delegate that called us is i, and it's currently in either
// Accept() or Cancel(). This means that the owning InfoBar will call
// RemoveInfoBar() later on, and that will trigger a notification we're
// observing.
++i;
- } else if (i->infobar_delegate) {
+ } else if (i->has_infobar_delegate()) {
// This InfoBar is for the same frame/embedder pair, but in a different
// tab. We should remove it now that we've got an answer for it.
infobars_to_remove.push_back(*i);
@@ -229,17 +200,13 @@
// Remove all InfoBars for the same |requesting_frame| and |embedder|.
for (PendingInfoBarRequests::iterator i = infobars_to_remove.begin();
- i != infobars_to_remove.end(); ++i ) {
- InfoBarTabHelper* helper = GetInfoBarHelper(i->render_process_id,
- i->render_view_id);
- helper->RemoveInfoBar(i->infobar_delegate);
- }
+ i != infobars_to_remove.end(); ++i)
+ GetInfoBarHelper(i->id())->RemoveInfoBar(i->infobar_delegate());
// Send out the permission notifications.
for (PendingInfoBarRequests::iterator i = requests_to_notify.begin();
- i != requests_to_notify.end(); ++i ) {
- i->callback.Run(allowed);
- }
+ i != requests_to_notify.end(); ++i)
+ i->RunCallback(allowed);
}
void GeolocationInfoBarQueueController::Observe(
@@ -260,86 +227,68 @@
content::Details<InfoBarRemovedDetails>(details)->first;
for (PendingInfoBarRequests::iterator i = pending_infobar_requests_.begin();
i != pending_infobar_requests_.end(); ++i) {
- GeolocationConfirmInfoBarDelegate* confirm_delegate = i->infobar_delegate;
+ GeolocationConfirmInfoBarDelegate* confirm_delegate = i->infobar_delegate();
if (confirm_delegate == delegate) {
- InfoBarTabHelper* helper =
- content::Source<InfoBarTabHelper>(source).ptr();
- int render_process_id = i->render_process_id;
- int render_view_id = i->render_view_id;
+ GeolocationPermissionRequestID id(i->id());
pending_infobar_requests_.erase(i);
- ShowQueuedInfoBar(render_process_id, render_view_id, helper);
+ ShowQueuedInfoBarForTab(id);
return;
}
}
}
-GeolocationConfirmInfoBarDelegate*
-GeolocationInfoBarQueueController::CreateInfoBarDelegate(
- InfoBarTabHelper* infobar_helper,
- GeolocationInfoBarQueueController* controller,
- int render_process_id,
- int render_view_id,
- int bridge_id,
- const GURL& requesting_frame_url,
- const std::string& display_languages) {
- return GeolocationConfirmInfoBarDelegateFactory::Create(
- infobar_helper, controller, render_process_id, render_view_id, bridge_id,
- requesting_frame_url, display_languages);
+bool GeolocationInfoBarQueueController::AlreadyShowingInfoBarForTab(
+ const GeolocationPermissionRequestID& id) const {
+ for (PendingInfoBarRequests::const_iterator i(
+ pending_infobar_requests_.begin());
+ i != pending_infobar_requests_.end(); ++i) {
+ if (i->id().IsForSameTabAs(id) && i->has_infobar_delegate())
+ return true;
+ }
+ return false;
}
-void GeolocationInfoBarQueueController::ShowQueuedInfoBar(
- int render_process_id,
- int render_view_id,
- InfoBarTabHelper* helper) {
- DCHECK(helper);
- DCHECK(!AlreadyShowingInfoBar(render_process_id, render_view_id));
+void GeolocationInfoBarQueueController::ShowQueuedInfoBarForTab(
+ const GeolocationPermissionRequestID& id) {
+ DCHECK(!AlreadyShowingInfoBarForTab(id));
+
+ InfoBarTabHelper* helper = GetInfoBarHelper(id);
+ if (!helper) {
+ // We can get here for example during tab shutdown, when the
+ // InfoBarTabHelper is removing all existing infobars, thus calling back to
+ // Observe(). In this case the helper still exists, and is supplied as the
+ // source of the notification we observed, but is no longer accessible from
+ // its WebContents. In this case we should just go ahead and cancel further
+ // infobars for this tab instead of trying to access the helper.
+ ClearPendingInfoBarRequestsForTab(id);
+ return;
+ }
+
for (PendingInfoBarRequests::iterator i = pending_infobar_requests_.begin();
i != pending_infobar_requests_.end(); ++i) {
- if (i->IsForTab(render_process_id, render_view_id) &&
- !i->infobar_delegate) {
+ if (i->id().IsForSameTabAs(id) && !i->has_infobar_delegate()) {
RegisterForInfoBarNotifications(helper);
- i->infobar_delegate = CreateInfoBarDelegate(
- helper, this, render_process_id,
- render_view_id, i->bridge_id, i->requesting_frame,
- profile_->GetPrefs()->GetString(prefs::kAcceptLanguages));
- helper->AddInfoBar(i->infobar_delegate);
+ i->CreateInfoBarDelegate(
+ this, profile_->GetPrefs()->GetString(prefs::kAcceptLanguages));
+ helper->AddInfoBar(i->infobar_delegate());
return;
}
}
+
UnregisterForInfoBarNotifications(helper);
}
void GeolocationInfoBarQueueController::ClearPendingInfoBarRequestsForTab(
- int render_process_id,
- int render_view_id) {
+ const GeolocationPermissionRequestID& id) {
for (PendingInfoBarRequests::iterator i = pending_infobar_requests_.begin();
i != pending_infobar_requests_.end(); ) {
- if (i->IsForTab(render_process_id, render_view_id))
+ if (i->id().IsForSameTabAs(id))
i = pending_infobar_requests_.erase(i);
else
++i;
}
}
-InfoBarTabHelper* GeolocationInfoBarQueueController::GetInfoBarHelper(
- int render_process_id,
- int render_view_id) {
- WebContents* web_contents =
- tab_util::GetWebContentsByID(render_process_id, render_view_id);
- return web_contents ? InfoBarTabHelper::FromWebContents(web_contents) : NULL;
-}
-
-bool GeolocationInfoBarQueueController::AlreadyShowingInfoBar(
- int render_process_id,
- int render_view_id) {
- for (PendingInfoBarRequests::iterator i = pending_infobar_requests_.begin();
- i != pending_infobar_requests_.end(); ++i) {
- if (i->IsForTab(render_process_id, render_view_id) && i->infobar_delegate)
- return true;
- }
- return false;
-}
-
void GeolocationInfoBarQueueController::RegisterForInfoBarNotifications(
InfoBarTabHelper* helper) {
if (!registrar_.IsRegistered(

Powered by Google App Engine
This is Rietveld 408576698