Index: chrome/browser/ui/website_settings/permission_bubble_manager.cc |
diff --git a/chrome/browser/ui/website_settings/permission_bubble_manager.cc b/chrome/browser/ui/website_settings/permission_bubble_manager.cc |
index 8816cee26ffea3ff1ebdfce6c6eca5b28a27a6e7..753ff100c03b5e403d7914d1dea65d8124f9ae51 100644 |
--- a/chrome/browser/ui/website_settings/permission_bubble_manager.cc |
+++ b/chrome/browser/ui/website_settings/permission_bubble_manager.cc |
@@ -9,6 +9,7 @@ |
#include "chrome/browser/ui/website_settings/permission_bubble_request.h" |
#include "chrome/common/chrome_switches.h" |
#include "content/public/browser/browser_thread.h" |
+#include "content/public/browser/navigation_details.h" |
#include "content/public/browser/user_metrics.h" |
namespace { |
@@ -101,46 +102,38 @@ void PermissionBubbleManager::AddRequest(PermissionBubbleRequest* request) { |
// correct behavior on interstitials -- we probably want to basically queue |
// any request for which GetVisibleURL != GetLastCommittedURL. |
request_url_ = web_contents()->GetLastCommittedURL(); |
+ bool is_main_frame = request->GetRequestingHostname() == request_url_; |
Greg Billock
2014/05/21 17:09:19
Do we need to extract just the hostport from the r
leng
2014/05/22 00:08:47
I have no idea. I don't know enough about main fr
Greg Billock
2014/05/22 02:06:31
I think GetLastCommittedURL() is the full url, and
leng
2014/05/22 23:57:05
Got it. I changed it to use GetOrigin() for both
|
// Don't re-add an existing request or one with a duplicate text request. |
- std::vector<PermissionBubbleRequest*>::iterator requests_iter; |
- for (requests_iter = requests_.begin(); |
- requests_iter != requests_.end(); |
- requests_iter++) { |
- if (*requests_iter == request) |
- return; |
- // TODO(gbillock): worry about the requesting host name as well. |
- if ((*requests_iter)->GetMessageTextFragment() == |
- request->GetMessageTextFragment()) { |
+ bool exact_duplicate = false; |
+ if (ExistingRequest(request, requests_, &exact_duplicate) || |
Greg Billock
2014/05/21 17:09:19
Maybe exact_duplicate --> same_object ?
leng
2014/05/22 00:08:47
Good call. Done.
|
+ ExistingRequest(request, queued_requests_, &exact_duplicate) || |
+ ExistingRequest(request, queued_frame_requests_, &exact_duplicate)) { |
+ if (!exact_duplicate) |
request->RequestFinished(); |
- return; |
- } |
- } |
- for (requests_iter = queued_requests_.begin(); |
- requests_iter != queued_requests_.end(); |
- requests_iter++) { |
- if (*requests_iter == request) |
- return; |
- if ((*requests_iter)->GetMessageTextFragment() == |
- request->GetMessageTextFragment()) { |
- request->RequestFinished(); |
- return; |
- } |
+ return; |
} |
if (bubble_showing_) { |
content::RecordAction( |
base::UserMetricsAction("PermissionBubbleRequestQueued")); |
- queued_requests_.push_back(request); |
+ if (is_main_frame) |
+ queued_requests_.push_back(request); |
+ else |
+ queued_frame_requests_.push_back(request); |
return; |
} |
- requests_.push_back(request); |
+ if (is_main_frame) |
+ requests_.push_back(request); |
+ else |
+ queued_frame_requests_.push_back(request); |
+ |
// TODO(gbillock): do we need to make default state a request property? |
accept_states_.push_back(true); |
Greg Billock
2014/05/21 17:09:19
should this only execute if is_main_frame, right?
leng
2014/05/22 00:08:47
Done.
|
if (request->HasUserGesture()) |
- ShowBubble(); |
+ TriggerShowBubble(); |
Greg Billock
2014/05/21 17:09:19
Should this be ScheduleShowBubble, right? (and was
leng
2014/05/22 00:08:47
I see no harm in making it ScheduleShowBubble(), a
|
} |
void PermissionBubbleManager::CancelRequest(PermissionBubbleRequest* request) { |
@@ -172,7 +165,7 @@ void PermissionBubbleManager::CancelRequest(PermissionBubbleRequest* request) { |
(*requests_iter)->RequestFinished(); |
requests_.erase(requests_iter); |
accept_states_.erase(accepts_iter); |
- ShowBubble(); // Will redraw the bubble if it is being shown. |
+ TriggerShowBubble(); // Will redraw the bubble if it is being shown. |
return; |
} |
@@ -203,7 +196,7 @@ void PermissionBubbleManager::SetView(PermissionBubbleView* view) { |
return; |
view->SetDelegate(this); |
- ShowBubble(); |
+ TriggerShowBubble(); |
} |
void PermissionBubbleManager::DocumentOnLoadCompletedInMainFrame() { |
@@ -213,11 +206,15 @@ void PermissionBubbleManager::DocumentOnLoadCompletedInMainFrame() { |
// callbacks finding the UI thread still. This makes sure we allow those |
// scheduled calls to AddRequest to complete before we show the page-load |
// permissions bubble. |
- // TODO(gbillock): make this bind safe with a weak ptr. |
- content::BrowserThread::PostTask( |
- content::BrowserThread::UI, FROM_HERE, |
- base::Bind(&PermissionBubbleManager::ShowBubble, |
- weak_factory_.GetWeakPtr())); |
+ ScheduleShowBubble(); |
+} |
+ |
+void PermissionBubbleManager::DocumentLoadedInFrame( |
+ int64 frame_id, |
+ content::RenderViewHost* render_view_host) { |
+ if (request_url_has_loaded_) { |
Greg Billock
2014/05/21 17:09:19
no braces
leng
2014/05/22 00:08:47
Done.
|
+ ScheduleShowBubble(); |
+ } |
} |
void PermissionBubbleManager::NavigationEntryCommitted( |
@@ -226,8 +223,9 @@ void PermissionBubbleManager::NavigationEntryCommitted( |
if (request_url_.is_empty()) |
return; |
- // If we have navigated to a new url... |
- if (request_url_ != web_contents()->GetLastCommittedURL()) { |
+ // If we have navigated to a new url or reloaded the page... |
+ if (request_url_ != web_contents()->GetLastCommittedURL() || |
+ details.type == content::NAVIGATION_TYPE_EXISTING_PAGE) { |
Greg Billock
2014/05/21 17:09:19
Makes sense. We then get the re-notifications for
leng
2014/05/22 00:08:47
Correct. I tested it manually.
|
// Kill off existing bubble and cancel any pending requests. |
CancelPendingQueue(); |
FinalizeBubble(); |
@@ -292,16 +290,32 @@ void PermissionBubbleManager::Closing() { |
FinalizeBubble(); |
} |
-// TODO(gbillock): find a better name for this method. |
-void PermissionBubbleManager::ShowBubble() { |
+void PermissionBubbleManager::ScheduleShowBubble() { |
+ content::BrowserThread::PostTask( |
+ content::BrowserThread::UI, FROM_HERE, |
+ base::Bind(&PermissionBubbleManager::TriggerShowBubble, |
+ weak_factory_.GetWeakPtr())); |
+} |
+ |
+void PermissionBubbleManager::TriggerShowBubble() { |
if (!view_) |
return; |
- if (requests_.empty()) |
- return; |
if (bubble_showing_) |
return; |
if (!request_url_has_loaded_) |
return; |
+ if (requests_.empty() && |
+ queued_requests_.empty() && |
+ queued_frame_requests_.empty()) |
+ return; |
+ |
+ if (requests_.empty()) { |
+ if (queued_requests_.size()) |
+ requests_.swap(queued_requests_); |
+ else |
+ requests_.swap(queued_frame_requests_); |
+ accept_states_.resize(requests_.size(), true); |
Greg Billock
2014/05/21 17:09:19
Maybe a comment that the 'true' here is setting th
leng
2014/05/22 00:08:47
Done.
|
+ } |
// Note: this should appear above Show() for testing, since in that |
// case we may do in-line calling of finalization. |
@@ -322,11 +336,8 @@ void PermissionBubbleManager::FinalizeBubble() { |
} |
requests_.clear(); |
accept_states_.clear(); |
- if (queued_requests_.size()) { |
- requests_ = queued_requests_; |
- accept_states_.resize(requests_.size(), true); |
- queued_requests_.clear(); |
- ShowBubble(); |
+ if (queued_requests_.size() || queued_frame_requests_.size()) { |
+ TriggerShowBubble(); |
} else { |
request_url_ = GURL(); |
} |
@@ -340,3 +351,28 @@ void PermissionBubbleManager::CancelPendingQueue() { |
(*requests_iter)->RequestFinished(); |
} |
} |
+ |
+bool PermissionBubbleManager::ExistingRequest( |
+ PermissionBubbleRequest* request, |
+ const std::vector<PermissionBubbleRequest*>& queue, |
+ bool* exact_duplicate) { |
+ std::vector<PermissionBubbleRequest*>::const_iterator iter; |
+ for (iter = queue.begin(); |
Greg Billock
2014/05/21 17:09:19
fits on one line?
leng
2014/05/22 00:08:47
Done.
|
+ iter != queue.end(); |
+ iter++) { |
+ if (*iter == request) { |
+ if (exact_duplicate) |
Greg Billock
2014/05/21 17:09:19
we can stipulate that CHECK(exact_duplicate)
leng
2014/05/22 00:08:47
Done.
|
+ *exact_duplicate = true; |
+ return true; |
+ } |
+ if ((*iter)->GetMessageTextFragment() == |
+ request->GetMessageTextFragment() && |
+ (*iter)->GetRequestingHostname() == |
+ request->GetRequestingHostname()) { |
+ if (exact_duplicate) |
+ *exact_duplicate = false; |
+ return true; |
+ } |
+ } |
+ return false; |
+} |