summaryrefslogtreecommitdiffstats
path: root/android_webview
diff options
context:
space:
mode:
authormichaelbai <michaelbai@chromium.org>2015-08-04 12:34:38 -0700
committerCommit bot <commit-bot@chromium.org>2015-08-04 19:36:31 +0000
commit97d22bb63d36d4d3049ef8f4009503acefb72bc9 (patch)
treecca8251a7979000002284b01685c788f24fc0e49 /android_webview
parent1094ea7173c15ba9c0df32204288deb2f6863315 (diff)
downloadchromium_src-97d22bb63d36d4d3049ef8f4009503acefb72bc9.zip
chromium_src-97d22bb63d36d4d3049ef8f4009503acefb72bc9.tar.gz
chromium_src-97d22bb63d36d4d3049ef8f4009503acefb72bc9.tar.bz2
Deny the geolocation permission request by default.
This patch denies the request if there is no response when GeolocationPermission.Callback object is gc-ed. BUG=513752 Review URL: https://codereview.chromium.org/1267103003 Cr-Commit-Position: refs/heads/master@{#341760}
Diffstat (limited to 'android_webview')
-rw-r--r--android_webview/java/src/org/chromium/android_webview/AwContents.java28
-rw-r--r--android_webview/java/src/org/chromium/android_webview/permission/AwGeolocationCallback.java76
-rw-r--r--android_webview/javatests/src/org/chromium/android_webview/test/GeolocationTest.java79
-rw-r--r--android_webview/native/aw_contents.cc8
4 files changed, 144 insertions, 47 deletions
diff --git a/android_webview/java/src/org/chromium/android_webview/AwContents.java b/android_webview/java/src/org/chromium/android_webview/AwContents.java
index a0e3278..8040d06 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwContents.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwContents.java
@@ -37,11 +37,11 @@ import android.view.accessibility.AccessibilityNodeProvider;
import android.view.animation.AnimationUtils;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
-import android.webkit.GeolocationPermissions;
import android.webkit.JavascriptInterface;
import android.webkit.ValueCallback;
import android.widget.OverScroller;
+import org.chromium.android_webview.permission.AwGeolocationCallback;
import org.chromium.android_webview.permission.AwPermissionRequest;
import org.chromium.base.ThreadUtils;
import org.chromium.base.TraceEvent;
@@ -2441,25 +2441,13 @@ public class AwContents implements SmartClipProvider,
mContentsClient.onReceivedHttpAuthRequest(handler, host, realm);
}
- private class AwGeolocationCallback implements GeolocationPermissions.Callback {
+ public AwGeolocationPermissions getGeolocationPermissions() {
+ return mBrowserContext.getGeolocationPermissions();
+ }
- @Override
- public void invoke(final String origin, final boolean allow, final boolean retain) {
- ThreadUtils.runOnUiThread(new Runnable() {
- @Override
- public void run() {
- if (retain) {
- if (allow) {
- mBrowserContext.getGeolocationPermissions().allow(origin);
- } else {
- mBrowserContext.getGeolocationPermissions().deny(origin);
- }
- }
- if (isDestroyed()) return;
- nativeInvokeGeolocationCallback(mNativeAwContents, allow, origin);
- }
- });
- }
+ public void invokeGeolocationCallback(boolean value, String requestingFrame) {
+ if (isDestroyed()) return;
+ nativeInvokeGeolocationCallback(mNativeAwContents, value, requestingFrame);
}
@CalledByNative
@@ -2478,7 +2466,7 @@ public class AwContents implements SmartClipProvider,
return;
}
mContentsClient.onGeolocationPermissionsShowPrompt(
- origin, new AwGeolocationCallback());
+ origin, new AwGeolocationCallback(origin, this));
}
@CalledByNative
diff --git a/android_webview/java/src/org/chromium/android_webview/permission/AwGeolocationCallback.java b/android_webview/java/src/org/chromium/android_webview/permission/AwGeolocationCallback.java
new file mode 100644
index 0000000..ef084f7
--- /dev/null
+++ b/android_webview/java/src/org/chromium/android_webview/permission/AwGeolocationCallback.java
@@ -0,0 +1,76 @@
+// Copyright 2015 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.permission;
+
+import android.webkit.GeolocationPermissions;
+
+import org.chromium.android_webview.AwContents;
+import org.chromium.base.Log;
+import org.chromium.base.ThreadUtils;
+import org.chromium.content.common.CleanupReference;
+
+import java.lang.ref.WeakReference;
+
+/**
+ * This class implements GeolocationPermissions.Callback, and will be sent to
+ * WebView applications through WebChromeClient.onGeolocationPermissionsShowPrompt().
+ */
+public class AwGeolocationCallback implements GeolocationPermissions.Callback {
+ private static final String TAG = "cr.Geolocation";
+
+ private CleanupRunable mCleanupRunable;
+ private CleanupReference mCleanupReference;
+
+ private static class CleanupRunable implements Runnable {
+ private WeakReference<AwContents> mAwContents;
+ private boolean mAllow;
+ private boolean mRetain;
+ private String mOrigin;
+
+ public CleanupRunable(AwContents awContents, String origin) {
+ mAwContents = new WeakReference<AwContents>(awContents);
+ mOrigin = origin;
+ }
+
+ @Override
+ public void run() {
+ assert ThreadUtils.runningOnUiThread();
+ AwContents awContents = mAwContents.get();
+ if (awContents == null) return;
+ if (mRetain) {
+ if (mAllow) {
+ awContents.getGeolocationPermissions().allow(mOrigin);
+ } else {
+ awContents.getGeolocationPermissions().deny(mOrigin);
+ }
+ }
+ awContents.invokeGeolocationCallback(mAllow, mOrigin);
+ }
+
+ public void setResponse(String origin, boolean allow, boolean retain) {
+ mOrigin = origin;
+ mAllow = allow;
+ mRetain = retain;
+ }
+ }
+
+ public AwGeolocationCallback(String origin, AwContents awContents) {
+ mCleanupRunable = new CleanupRunable(awContents, origin);
+ mCleanupReference = new CleanupReference(this, mCleanupRunable);
+ }
+
+ @Override
+ public void invoke(String origin, boolean allow, boolean retain) {
+ if (mCleanupRunable == null || mCleanupReference == null) {
+ Log.w(TAG, "Response for this geolocation request has been received."
+ + " Ignoring subsequent responses");
+ return;
+ }
+ mCleanupRunable.setResponse(origin, allow, retain);
+ mCleanupReference.cleanupNow();
+ mCleanupReference = null;
+ mCleanupRunable = null;
+ }
+}
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/GeolocationTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/GeolocationTest.java
index 23beb13..e66c39f 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/GeolocationTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/GeolocationTest.java
@@ -6,9 +6,11 @@ package org.chromium.android_webview.test;
import android.os.Build;
import android.test.suitebuilder.annotation.MediumTest;
+import android.test.suitebuilder.annotation.SmallTest;
import android.webkit.GeolocationPermissions;
import org.chromium.android_webview.AwContents;
+import org.chromium.base.annotations.SuppressFBWarnings;
import org.chromium.base.test.util.Feature;
import org.chromium.base.test.util.MinAndroidSdkLevel;
import org.chromium.content.browser.LocationProviderFactory;
@@ -37,13 +39,17 @@ public class GeolocationTest extends AwTestBase {
+ " function gotPos(position) {\n"
+ " positionCount++;\n"
+ " }\n"
+ + " function errorCallback(error){"
+ + " window.document.title = 'deny';"
+ + " console.log('navigator.getCurrentPosition error: ', error);"
+ + " }"
+ " function initiate_getCurrentPosition() {\n"
+ " navigator.geolocation.getCurrentPosition(\n"
- + " gotPos, function() { }, { });\n"
+ + " gotPos, errorCallback, { });\n"
+ " }\n"
+ " function initiate_watchPosition() {\n"
+ " navigator.geolocation.watchPosition(\n"
- + " gotPos, function() { }, { });\n"
+ + " gotPos, errorCallback, { });\n"
+ " }\n"
+ " </script>\n"
+ " </head>\n"
@@ -51,38 +57,47 @@ public class GeolocationTest extends AwTestBase {
+ " </body>\n"
+ "</html>";
- @Override
- public void setUp() throws Exception {
- super.setUp();
- mContentsClient = new TestAwContentsClient() {
- @Override
- public void onGeolocationPermissionsShowPrompt(String origin,
- GeolocationPermissions.Callback callback) {
- callback.invoke(origin, true, true);
- }
- };
- mAwContents = createAwTestContainerViewOnMainSync(mContentsClient).getAwContents();
- enableJavaScriptOnUiThread(mAwContents);
- setupGeolocation();
+ private static class GrantPermisionAwContentClient extends TestAwContentsClient {
+ @Override
+ public void onGeolocationPermissionsShowPrompt(String origin,
+ GeolocationPermissions.Callback callback) {
+ callback.invoke(origin, true, true);
+ }
}
- @Override
- public void tearDown() throws Exception {
- mMockLocationProvider.stopUpdates();
- super.tearDown();
+ private static class DefaultPermisionAwContentClient extends TestAwContentsClient {
+ @Override
+ public void onGeolocationPermissionsShowPrompt(String origin,
+ GeolocationPermissions.Callback callback) {
+ // This method is empty intentionally to simulate callback is not referenced.
+ }
}
- private void setupGeolocation() {
+ private void initAwContents(TestAwContentsClient contentsClient) throws Exception {
+ mContentsClient = contentsClient;
+ mAwContents = createAwTestContainerViewOnMainSync(mContentsClient).getAwContents();
+ enableJavaScriptOnUiThread(mAwContents);
getInstrumentation().runOnMainSync(new Runnable() {
@Override
public void run() {
mAwContents.getSettings().setGeolocationEnabled(true);
}
});
+ }
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
mMockLocationProvider = new MockLocationProvider();
LocationProviderFactory.setLocationProviderImpl(mMockLocationProvider);
}
+ @Override
+ public void tearDown() throws Exception {
+ mMockLocationProvider.stopUpdates();
+ super.tearDown();
+ }
+
private int getPositionCountFromJS() {
int result = -1;
try {
@@ -110,6 +125,7 @@ public class GeolocationTest extends AwTestBase {
@MediumTest
@Feature({"AndroidWebView"})
public void testGetPosition() throws Throwable {
+ initAwContents(new GrantPermisionAwContentClient());
loadDataSync(mAwContents, mContentsClient.getOnPageFinishedHelper(),
RAW_HTML, "text/html", false);
@@ -137,6 +153,7 @@ public class GeolocationTest extends AwTestBase {
@MediumTest
@Feature({"AndroidWebView"})
public void testWatchPosition() throws Throwable {
+ initAwContents(new GrantPermisionAwContentClient());
loadDataSync(mAwContents, mContentsClient.getOnPageFinishedHelper(),
RAW_HTML, "text/html", false);
@@ -153,6 +170,7 @@ public class GeolocationTest extends AwTestBase {
@MediumTest
@Feature({"AndroidWebView"})
public void testPauseGeolocationOnPause() throws Throwable {
+ initAwContents(new GrantPermisionAwContentClient());
// Start a watch going.
loadDataSync(mAwContents, mContentsClient.getOnPageFinishedHelper(),
RAW_HTML, "text/html", false);
@@ -204,6 +222,7 @@ public class GeolocationTest extends AwTestBase {
@MediumTest
@Feature({"AndroidWebView"})
public void testPauseAwContentsBeforeNavigating() throws Throwable {
+ initAwContents(new GrantPermisionAwContentClient());
getInstrumentation().runOnMainSync(new Runnable() {
@Override
public void run() {
@@ -241,6 +260,7 @@ public class GeolocationTest extends AwTestBase {
@MediumTest
@Feature({"AndroidWebView"})
public void testResumeWhenNotStarted() throws Throwable {
+ initAwContents(new GrantPermisionAwContentClient());
getInstrumentation().runOnMainSync(new Runnable() {
@Override
public void run() {
@@ -261,4 +281,23 @@ public class GeolocationTest extends AwTestBase {
ensureGeolocationRunning(false);
}
+ @Feature({"AndroidWebView"})
+ @SmallTest
+ public void testDenyAccessByDefault() throws Throwable {
+ initAwContents(new DefaultPermisionAwContentClient());
+ loadDataSync(mAwContents, mContentsClient.getOnPageFinishedHelper(),
+ RAW_HTML, "text/html", false);
+
+ mAwContents.evaluateJavaScriptForTests("initiate_getCurrentPosition();", null);
+
+ poll(new Callable<Boolean>() {
+ @SuppressFBWarnings("DM_GC")
+ @Override
+ public Boolean call() throws Exception {
+ Runtime.getRuntime().gc();
+ return "deny".equals(getTitleOnUiThread(mAwContents));
+ }
+ });
+ }
+
}
diff --git a/android_webview/native/aw_contents.cc b/android_webview/native/aw_contents.cc
index d926404..58782a8 100644
--- a/android_webview/native/aw_contents.cc
+++ b/android_webview/native/aw_contents.cc
@@ -491,11 +491,8 @@ void AwContents::InvokeGeolocationCallback(JNIEnv* env,
jboolean value,
jstring origin) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- if (pending_geolocation_prompts_.empty()) {
- LOG(WARNING) << "Response for this geolocation request has been received."
- << " Ignoring subsequent responses";
+ if (pending_geolocation_prompts_.empty())
return;
- }
GURL callback_origin(base::android::ConvertJavaStringToUTF16(env, origin));
if (callback_origin.GetOrigin() ==
@@ -506,9 +503,6 @@ void AwContents::InvokeGeolocationCallback(JNIEnv* env,
ShowGeolocationPromptHelper(java_ref_,
pending_geolocation_prompts_.front().first);
}
- } else {
- LOG(WARNING) << "Response for this geolocation request has been received."
- << " Ignoring subsequent responses";
}
}