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

Unified Diff: chrome/browser/notifications/notification_permission_context.cc

Issue 1702633002: Fix crash due to VisibilityTimerTabHelper not being cancelled (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 10 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/notifications/notification_permission_context.cc
diff --git a/chrome/browser/notifications/notification_permission_context.cc b/chrome/browser/notifications/notification_permission_context.cc
index 9e21d0c1e5e93554238051619c2236ea97f63358..73cc1a28d09cff9a1055df01e44a6d30ed376806 100644
--- a/chrome/browser/notifications/notification_permission_context.cc
+++ b/chrome/browser/notifications/notification_permission_context.cc
@@ -4,7 +4,8 @@
#include "chrome/browser/notifications/notification_permission_context.h"
-#include <queue>
+#include <algorithm>
+#include <deque>
#include "base/callback.h"
#include "base/location.h"
@@ -38,7 +39,10 @@ class VisibilityTimerTabHelper
// duration of at least |visible_delay|.
void PostTaskAfterVisibleDelay(const tracked_objects::Location& from_here,
const base::Closure& task,
- base::TimeDelta visible_delay);
+ base::TimeDelta visible_delay,
+ const PermissionRequestID& id);
+
+ void CancelTask(const PermissionRequestID& id);
Peter Beverloo 2016/02/16 15:28:28 +docs
johnme 2016/02/16 18:14:34 Done.
// WebContentsObserver:
void WasShown() override;
@@ -52,7 +56,9 @@ class VisibilityTimerTabHelper
void RunTask(const base::Closure& task);
bool is_visible_;
- std::queue<scoped_ptr<base::Timer>> task_queue_;
+
+ typedef std::pair<PermissionRequestID, scoped_ptr<base::Timer>> TaskEntry;
Peter Beverloo 2016/02/16 15:28:28 Could you define a small structure instead? |task_
johnme 2016/02/16 18:14:34 Done.
+ std::deque<TaskEntry> task_queue_;
DISALLOW_COPY_AND_ASSIGN(VisibilityTimerTabHelper);
};
@@ -78,27 +84,46 @@ VisibilityTimerTabHelper::VisibilityTimerTabHelper(
void VisibilityTimerTabHelper::PostTaskAfterVisibleDelay(
const tracked_objects::Location& from_here,
const base::Closure& task,
- base::TimeDelta visible_delay) {
+ base::TimeDelta visible_delay,
+ const PermissionRequestID& id) {
// Safe to use Unretained, as destroying this will destroy task_queue_, hence
// cancelling all timers.
- task_queue_.push(make_scoped_ptr(new base::Timer(
- from_here, visible_delay, base::Bind(&VisibilityTimerTabHelper::RunTask,
- base::Unretained(this), task),
- false /* is_repeating */)));
- DCHECK(!task_queue_.back()->IsRunning());
+ task_queue_.push_back(
+ std::make_pair(id, make_scoped_ptr(new base::Timer(
+ from_here, visible_delay,
+ base::Bind(&VisibilityTimerTabHelper::RunTask,
+ base::Unretained(this), task),
+ false /* is_repeating */))));
Peter Beverloo 2016/02/16 15:28:28 nit: readability ===== scoped_ptr<base::Timer>
johnme 2016/02/16 18:14:34 Done.
+ DCHECK(!task_queue_.back().second->IsRunning());
if (is_visible_ && task_queue_.size() == 1)
- task_queue_.front()->Reset();
+ task_queue_.front().second->Reset();
+}
+
+void VisibilityTimerTabHelper::CancelTask(const PermissionRequestID& id) {
+ bool deleting_front = task_queue_.front().first == id;
+ task_queue_.erase(std::remove_if(task_queue_.begin(), task_queue_.end(),
+ [id](const TaskEntry& entry) {
+ return entry.first == id;
+ }),
+ task_queue_.end());
+ if (!task_queue_.empty()) {
+ if (is_visible_ && deleting_front)
+ task_queue_.front().second->Reset();
+ return;
+ }
+ web_contents()->RemoveUserData(UserDataKey());
Peter Beverloo 2016/02/16 15:28:28 What is the significance of eagerly deleting |this
johnme 2016/02/16 18:14:34 It seemed neater at the time, but it adds a bunch
+ // |this| has been deleted now.
}
void VisibilityTimerTabHelper::WasShown() {
if (!is_visible_ && !task_queue_.empty())
- task_queue_.front()->Reset();
+ task_queue_.front().second->Reset();
is_visible_ = true;
}
void VisibilityTimerTabHelper::WasHidden() {
if (is_visible_ && !task_queue_.empty())
- task_queue_.front()->Stop();
+ task_queue_.front().second->Stop();
is_visible_ = false;
}
@@ -111,9 +136,9 @@ void VisibilityTimerTabHelper::WebContentsDestroyed() {
void VisibilityTimerTabHelper::RunTask(const base::Closure& task) {
DCHECK(is_visible_);
task.Run();
- task_queue_.pop();
+ task_queue_.pop_front();
if (!task_queue_.empty()) {
- task_queue_.front()->Reset();
+ task_queue_.front().second->Reset();
return;
}
web_contents()->RemoveUserData(UserDataKey());
@@ -139,6 +164,16 @@ void NotificationPermissionContext::ResetPermission(
profile(), ContentSettingsPattern::FromURLNoWildcard(requesting_origin));
}
+void NotificationPermissionContext::CancelPermissionRequest(
+ content::WebContents* web_contents,
+ const PermissionRequestID& id) {
+ if (profile()->IsOffTheRecord()) {
+ VisibilityTimerTabHelper::FromWebContents(web_contents)->CancelTask(id);
+ } else {
+ PermissionContextBase::CancelPermissionRequest(web_contents, id);
+ }
+}
+
void NotificationPermissionContext::DecidePermission(
content::WebContents* web_contents,
const PermissionRequestID& id,
@@ -166,7 +201,7 @@ void NotificationPermissionContext::DecidePermission(
weak_factory_ui_thread_.GetWeakPtr(), id,
requesting_origin, embedding_origin, callback,
true /* persist */, CONTENT_SETTING_BLOCK),
- base::TimeDelta::FromSecondsD(delay_seconds));
+ base::TimeDelta::FromSecondsD(delay_seconds), id);
return;
}

Powered by Google App Engine
This is Rietveld 408576698