summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormichaelbai@chromium.org <michaelbai@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-05-28 18:25:34 +0000
committermichaelbai@chromium.org <michaelbai@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-05-28 18:25:34 +0000
commit9710193224e6f1106eaff11fcbeea19b2e5e146d (patch)
tree7a8589e922e121ecbace5aa66464cb48ca96d4dc
parent7367bd4dd13bdde4fe9ab71bb227646d74d1427a (diff)
downloadchromium_src-9710193224e6f1106eaff11fcbeea19b2e5e146d.zip
chromium_src-9710193224e6f1106eaff11fcbeea19b2e5e146d.tar.gz
chromium_src-9710193224e6f1106eaff11fcbeea19b2e5e146d.tar.bz2
Merge 271650 "Cancel the permission request when webview navigat..."
> Cancel the permission request when webview navigates to different page or reload. > > BUG=373352 > > Review URL: https://codereview.chromium.org/288463003 TBR=michaelbai@chromium.org Review URL: https://codereview.chromium.org/300323002 git-svn-id: svn://svn.chromium.org/chrome/branches/1985/src@273296 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--android_webview/javatests/src/org/chromium/android_webview/test/MediaAccessPermissionRequestTest.java157
-rw-r--r--android_webview/native/aw_contents.cc3
-rw-r--r--android_webview/native/permission/permission_request_handler.cc41
-rw-r--r--android_webview/native/permission/permission_request_handler.h16
-rw-r--r--android_webview/native/permission/permission_request_handler_unittest.cc2
5 files changed, 211 insertions, 8 deletions
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/MediaAccessPermissionRequestTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/MediaAccessPermissionRequestTest.java
new file mode 100644
index 0000000..b4a132b
--- /dev/null
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/MediaAccessPermissionRequestTest.java
@@ -0,0 +1,157 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.android_webview.test;
+
+import android.test.suitebuilder.annotation.SmallTest;
+
+import org.chromium.android_webview.AwContents;
+import org.chromium.android_webview.permission.AwPermissionRequest;
+import org.chromium.android_webview.test.util.CommonResources;
+import org.chromium.base.test.util.Feature;
+import org.chromium.content.browser.test.util.CallbackHelper;
+import org.chromium.net.test.util.TestWebServer;
+
+import java.util.concurrent.Callable;
+
+/**
+ * Test MediaAccessPermissionRequest.
+ */
+public class MediaAccessPermissionRequestTest extends AwTestBase {
+ private static class OnPermissionRequestHelper extends CallbackHelper {
+ private boolean mCanceled;
+
+ public void notifyCanceled() {
+ mCanceled = true;
+ notifyCalled();
+ }
+
+ public boolean canceled() {
+ return mCanceled;
+ }
+ }
+
+ private final String mData = "<html> <script> " +
+ "var constraints = {audio: true, video: true};" +
+ "var video = document.querySelector('video');" +
+ "function successCallback(stream) {" +
+ "window.document.title = 'grant';" +
+ "if (window.URL) {" +
+ "video.src = window.URL.createObjectURL(stream);" +
+ "} else {" +
+ "video.src = stream;" +
+ "}" +
+ "}" +
+ "function errorCallback(error){" +
+ "window.document.title = 'deny';" +
+ "console.log('navigator.getUserMedia error: ', error);" +
+ "}" +
+ "navigator.webkitGetUserMedia(constraints, successCallback, errorCallback)" +
+ " </script><body>" +
+ "<video autoplay></video>" +
+ "</body></html>";
+
+ private TestWebServer mTestWebServer;
+ private String mWebRTCPage;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mTestWebServer = new TestWebServer(false);
+ mWebRTCPage = mTestWebServer.setResponse("/WebRTC", mData,
+ CommonResources.getTextHtmlHeaders(true));
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ mTestWebServer.shutdown();
+ mTestWebServer = null;
+ super.tearDown();
+ }
+
+ @Feature({"AndroidWebView"})
+ @SmallTest
+ public void testGrantAccess() throws Throwable {
+ final OnPermissionRequestHelper helper = new OnPermissionRequestHelper();
+ TestAwContentsClient contentsClient =
+ new TestAwContentsClient() {
+ @Override
+ public void onPermissionRequest(AwPermissionRequest awPermissionRequest) {
+ awPermissionRequest.grant();
+ helper.notifyCalled();
+ }
+ };
+ final AwTestContainerView testContainerView =
+ createAwTestContainerViewOnMainSync(contentsClient);
+ final AwContents awContents = testContainerView.getAwContents();
+ enableJavaScriptOnUiThread(awContents);
+ int callCount = helper.getCallCount();
+ loadUrlAsync(awContents, mWebRTCPage, null);
+ helper.waitForCallback(callCount);
+ pollTitleAs("grant", awContents);
+ }
+
+ @Feature({"AndroidWebView"})
+ @SmallTest
+ public void testDenyAccess() throws Throwable {
+ final OnPermissionRequestHelper helper = new OnPermissionRequestHelper();
+ TestAwContentsClient contentsClient =
+ new TestAwContentsClient() {
+ @Override
+ public void onPermissionRequest(AwPermissionRequest awPermissionRequest) {
+ awPermissionRequest.deny();
+ helper.notifyCalled();
+ }
+ };
+ final AwTestContainerView testContainerView =
+ createAwTestContainerViewOnMainSync(contentsClient);
+ final AwContents awContents = testContainerView.getAwContents();
+ enableJavaScriptOnUiThread(awContents);
+ int callCount = helper.getCallCount();
+ loadUrlAsync(awContents, mWebRTCPage, null);
+ helper.waitForCallback(callCount);
+ pollTitleAs("deny", awContents);
+ }
+
+ private void pollTitleAs(final String title, final AwContents awContents)
+ throws Exception {
+ poll(new Callable<Boolean>() {
+ @Override
+ public Boolean call() throws Exception {
+ return title.equals(getTitleOnUiThread(awContents));
+ }
+ });
+ }
+
+ @Feature({"AndroidWebView"})
+ @SmallTest
+ public void testCancelPermission() throws Throwable {
+ final OnPermissionRequestHelper helper = new OnPermissionRequestHelper();
+ TestAwContentsClient contentsClient =
+ new TestAwContentsClient() {
+ @Override
+ public void onPermissionRequest(AwPermissionRequest awPermissionRequest) {
+ // Don't respond and wait for the request canceled.
+ helper.notifyCalled();
+ }
+ @Override
+ public void onPermissionRequestCanceled(
+ AwPermissionRequest awPermissionRequest) {
+ helper.notifyCanceled();
+ }
+ };
+ final AwTestContainerView testContainerView =
+ createAwTestContainerViewOnMainSync(contentsClient);
+ final AwContents awContents = testContainerView.getAwContents();
+ enableJavaScriptOnUiThread(awContents);
+ int callCount = helper.getCallCount();
+ loadUrlAsync(awContents, mWebRTCPage, null);
+ helper.waitForCallback(callCount);
+ callCount = helper.getCallCount();
+ // Load the same page again, the previous request should be canceled.
+ loadUrlAsync(awContents, mWebRTCPage, null);
+ helper.waitForCallback(callCount);
+ assert (helper.canceled());
+ }
+}
diff --git a/android_webview/native/aw_contents.cc b/android_webview/native/aw_contents.cc
index d4b4e09..594f508 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() {