From 6db80a636416d87ac6e808aa3ecfb1d04e5f18a8 Mon Sep 17 00:00:00 2001
From: "michaelbai@chromium.org"
 <michaelbai@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>
Date: Tue, 20 May 2014 15:18:36 +0000
Subject: Cancel the permission request when webview navigates to different
 page or reload.

BUG=373352

Review URL: https://codereview.chromium.org/288463003

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@271650 0039d316-1c4b-4281-b951-d872f2087c98
---
 android_webview/native/aw_contents.cc              |  3 +-
 .../permission/permission_request_handler.cc       | 41 +++++++++++++++++++---
 .../native/permission/permission_request_handler.h | 16 +++++++--
 .../permission_request_handler_unittest.cc         |  2 +-
 4 files changed, 54 insertions(+), 8 deletions(-)

(limited to 'android_webview/native')

diff --git a/android_webview/native/aw_contents.cc b/android_webview/native/aw_contents.cc
index 91f6f9d..c0f7b1b 100644
--- a/android_webview/native/aw_contents.cc
+++ b/android_webview/native/aw_contents.cc
@@ -169,7 +169,8 @@ AwContents::AwContents(scoped_ptr<WebContents> web_contents)
   render_view_host_ext_.reset(
       new AwRenderViewHostExt(this, web_contents_.get()));
 
-  permission_request_handler_.reset(new PermissionRequestHandler(this));
+  permission_request_handler_.reset(
+      new PermissionRequestHandler(this, web_contents_.get()));
 
   AwAutofillManagerDelegate* autofill_manager_delegate =
       AwAutofillManagerDelegate::FromWebContents(web_contents_.get());
diff --git a/android_webview/native/permission/permission_request_handler.cc b/android_webview/native/permission/permission_request_handler.cc
index 20cc748..bb6cce3 100644
--- a/android_webview/native/permission/permission_request_handler.cc
+++ b/android_webview/native/permission/permission_request_handler.cc
@@ -9,19 +9,35 @@
 #include "android_webview/native/permission/permission_request_handler_client.h"
 #include "base/android/scoped_java_ref.h"
 #include "base/bind.h"
+#include "content/public/browser/navigation_details.h"
+#include "content/public/browser/navigation_entry.h"
+#include "content/public/browser/web_contents.h"
 
 using base::android::ScopedJavaLocalRef;
 
 namespace android_webview {
 
+namespace {
+
+int GetActiveEntryID(content::WebContents* web_contents) {
+  if (!web_contents) return 0;
+
+  content::NavigationEntry* active_entry =
+      web_contents->GetController().GetActiveEntry();
+  return active_entry ? active_entry->GetUniqueID() : 0;
+}
+
+}  // namespace
+
 PermissionRequestHandler::PermissionRequestHandler(
-    PermissionRequestHandlerClient* client)
-    : client_(client) {
+    PermissionRequestHandlerClient* client, content::WebContents* web_contents)
+    : content::WebContentsObserver(web_contents),
+      client_(client),
+      contents_unique_id_(GetActiveEntryID(web_contents)) {
 }
 
 PermissionRequestHandler::~PermissionRequestHandler() {
-  for (RequestIterator i = requests_.begin(); i != requests_.end(); ++i)
-    CancelRequest(i);
+  CancelAllRequests();
 }
 
 void PermissionRequestHandler::SendRequest(
@@ -64,6 +80,18 @@ void PermissionRequestHandler::PreauthorizePermission(const GURL& origin,
   preauthorized_permission_[key] |= resources;
 }
 
+void PermissionRequestHandler::NavigationEntryCommitted(
+    const content::LoadCommittedDetails& details) {
+  const content::PageTransition transition = details.entry->GetTransitionType();
+  if (details.is_navigation_to_different_page() ||
+      content::PageTransitionStripQualifier(transition) ==
+      content::PAGE_TRANSITION_RELOAD ||
+      contents_unique_id_ != details.entry->GetUniqueID()) {
+    CancelAllRequests();
+    contents_unique_id_ = details.entry->GetUniqueID();
+  }
+}
+
 PermissionRequestHandler::RequestIterator
 PermissionRequestHandler::FindRequest(const GURL& origin,
                                       int64 resources) {
@@ -87,6 +115,11 @@ void PermissionRequestHandler::CancelRequest(RequestIterator i) {
     delete i->get();
 }
 
+void PermissionRequestHandler::CancelAllRequests() {
+  for (RequestIterator i = requests_.begin(); i != requests_.end(); ++i)
+    CancelRequest(i);
+}
+
 void PermissionRequestHandler::PruneRequests() {
   for (RequestIterator i = requests_.begin(); i != requests_.end();) {
     if (!i->get())
diff --git a/android_webview/native/permission/permission_request_handler.h b/android_webview/native/permission/permission_request_handler.h
index 3acb497..69a9171 100644
--- a/android_webview/native/permission/permission_request_handler.h
+++ b/android_webview/native/permission/permission_request_handler.h
@@ -10,6 +10,7 @@
 
 #include "base/memory/scoped_ptr.h"
 #include "base/memory/weak_ptr.h"
+#include "content/public/browser/web_contents_observer.h"
 #include "url/gurl.h"
 
 namespace android_webview {
@@ -22,9 +23,10 @@ class PermissionRequestHandlerClient;
 // requests.
 // It is owned by AwContents and has 1x1 mapping to AwContents. All methods
 // are running on UI thread.
-class PermissionRequestHandler {
+class PermissionRequestHandler : public content::WebContentsObserver {
  public:
-  PermissionRequestHandler(PermissionRequestHandlerClient* aw_contents);
+  PermissionRequestHandler(PermissionRequestHandlerClient* client,
+                           content::WebContents* aw_contents);
   virtual ~PermissionRequestHandler();
 
   // Send the given |request| to PermissionRequestHandlerClient.
@@ -36,6 +38,10 @@ class PermissionRequestHandler {
   // Allow |origin| to access the |resources|.
   void PreauthorizePermission(const GURL& origin, int64 resources);
 
+  // WebContentsObserver
+  virtual void NavigationEntryCommitted(
+      const content::LoadCommittedDetails& load_details) OVERRIDE;
+
  private:
   friend class TestPermissionRequestHandler;
 
@@ -48,6 +54,8 @@ class PermissionRequestHandler {
   // Cancel the given request.
   void CancelRequest(RequestIterator i);
 
+  void CancelAllRequests();
+
   // Remove the invalid requests from requests_.
   void PruneRequests();
 
@@ -61,6 +69,10 @@ class PermissionRequestHandler {
 
   std::map<std::string, int64> preauthorized_permission_;
 
+  // The unique id of the active NavigationEntry of the WebContents that we were
+  // opened for. Used to help expire on requests.
+  int contents_unique_id_;
+
   DISALLOW_COPY_AND_ASSIGN(PermissionRequestHandler);
 };
 
diff --git a/android_webview/native/permission/permission_request_handler_unittest.cc b/android_webview/native/permission/permission_request_handler_unittest.cc
index 981170c..c709f0b 100644
--- a/android_webview/native/permission/permission_request_handler_unittest.cc
+++ b/android_webview/native/permission/permission_request_handler_unittest.cc
@@ -106,7 +106,7 @@ class TestPermissionRequestHandlerClient :
 class TestPermissionRequestHandler : public PermissionRequestHandler {
  public:
   TestPermissionRequestHandler(PermissionRequestHandlerClient* client)
-      : PermissionRequestHandler(client) {
+      : PermissionRequestHandler(client, NULL) {
   }
 
   const std::vector<base::WeakPtr<AwPermissionRequest> > requests() {
-- 
cgit v1.1