summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsgurun@chromium.org <sgurun@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-10-25 04:46:38 +0000
committersgurun@chromium.org <sgurun@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-10-25 04:46:38 +0000
commitc1a734423680e44bdfb85cf92cea5405708c9085 (patch)
treefa9894a9b038d12a9c0414b502aa14de71e29d25
parenta3f0f9e11c1047d1a7f434943ff9c799ce77e4d7 (diff)
downloadchromium_src-c1a734423680e44bdfb85cf92cea5405708c9085.zip
chromium_src-c1a734423680e44bdfb85cf92cea5405708c9085.tar.gz
chromium_src-c1a734423680e44bdfb85cf92cea5405708c9085.tar.bz2
Handle resubmission of HTTP Posts.
Implement functionality to handle resubmission of forms in Webview. BUG=None Review URL: https://chromiumcodereview.appspot.com/11187032 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@164014 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--android_webview/java/src/org/chromium/android_webview/AwContentsClient.java35
-rw-r--r--android_webview/javatests/src/org/chromium/android_webview/test/AndroidWebViewTestBase.java31
-rw-r--r--android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientOnFormResubmissionTest.java127
-rw-r--r--android_webview/javatests/src/org/chromium/android_webview/test/NullContentsClient.java6
-rw-r--r--chrome/browser/component/web_contents_delegate_android/DEPS1
-rw-r--r--chrome/browser/component/web_contents_delegate_android/java/src/org/chromium/chrome/browser/component/web_contents_delegate_android/WebContentsDelegateAndroid.java9
-rw-r--r--chrome/browser/component/web_contents_delegate_android/web_contents_delegate_android.cc15
-rw-r--r--chrome/browser/component/web_contents_delegate_android/web_contents_delegate_android.gypi1
-rw-r--r--chrome/browser/component/web_contents_delegate_android/web_contents_delegate_android.h3
-rw-r--r--content/browser/android/content_view_core_impl.cc10
-rw-r--r--content/browser/android/content_view_core_impl.h2
-rw-r--r--content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java18
12 files changed, 257 insertions, 1 deletions
diff --git a/android_webview/java/src/org/chromium/android_webview/AwContentsClient.java b/android_webview/java/src/org/chromium/android_webview/AwContentsClient.java
index 9cd3ba6..8951329 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwContentsClient.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwContentsClient.java
@@ -6,6 +6,9 @@ package org.chromium.android_webview;
import android.graphics.Rect;
import android.graphics.RectF;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
import android.util.Log;
import android.view.KeyEvent;
import android.webkit.ConsoleMessage;
@@ -38,6 +41,29 @@ public abstract class AwContentsClient extends ContentViewClient {
//--------------------------------------------------------------------------------------------
class WebContentsDelegateAdapter extends AwWebContentsDelegate {
+
+ // The message ids.
+ public final static int CONTINUE_PENDING_RELOAD = 1;
+ public final static int CANCEL_PENDING_RELOAD = 2;
+
+ // Handler associated with this adapter.
+ // TODO(sgurun) Remember the URL to cancel the resend behavior
+ // if it is different than the most recent NavigationController entry.
+ private final Handler mHandler = new Handler(Looper.getMainLooper()) {
+
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case CONTINUE_PENDING_RELOAD:
+ ((ContentViewCore) msg.obj).continuePendingReload();
+ break;
+ case CANCEL_PENDING_RELOAD:
+ ((ContentViewCore) msg.obj).cancelPendingReload();
+ break;
+ }
+ }
+ };
+
@Override
public void onLoadProgressChanged(int progress) {
AwContentsClient.this.onProgressChanged(progress);
@@ -100,6 +126,13 @@ public abstract class AwContentsClient extends ContentViewClient {
public void onUrlStarredChanged(boolean starred) {
// TODO: implement
}
+
+ @Override
+ public void showRepostFormWarningDialog(ContentViewCore contentViewCore) {
+ Message dontResend = mHandler.obtainMessage(CANCEL_PENDING_RELOAD, contentViewCore);
+ Message resend = mHandler.obtainMessage(CONTINUE_PENDING_RELOAD, contentViewCore);
+ AwContentsClient.this.onFormResubmission(dontResend, resend);
+ }
}
class AwWebContentsObserver extends WebContentsObserverAndroid {
@@ -167,6 +200,8 @@ public abstract class AwContentsClient extends ContentViewClient {
public abstract void onReceivedHttpAuthRequest(AwHttpAuthHandler handler,
String host, String realm);
+ public abstract void onFormResubmission(Message dontResend, Message resend);
+
protected abstract void handleJsAlert(String url, String message, JsResultReceiver receiver);
protected abstract void handleJsBeforeUnload(String url, String message,
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AndroidWebViewTestBase.java b/android_webview/javatests/src/org/chromium/android_webview/test/AndroidWebViewTestBase.java
index ad15bf1..c516b96 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/AndroidWebViewTestBase.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/AndroidWebViewTestBase.java
@@ -125,6 +125,37 @@ public class AndroidWebViewTestBase
}
/**
+ * Posts url on the UI thread and blocks until onPageFinished is called.
+ */
+ protected void postUrlSync(final AwContents awContents,
+ CallbackHelper onPageFinishedHelper, final String url,
+ byte[] postData) throws Throwable {
+ int currentCallCount = onPageFinishedHelper.getCallCount();
+ postUrlAsync(awContents, url, postData);
+ onPageFinishedHelper.waitForCallback(currentCallCount, 1, WAIT_TIMEOUT_SECONDS,
+ TimeUnit.SECONDS);
+ }
+
+ /**
+ * Loads url on the UI thread but does not block.
+ */
+ protected void postUrlAsync(final AwContents awContents,
+ final String url, byte[] postData) throws Throwable {
+ class PostUrl implements Runnable {
+ byte[] mPostData;
+ public PostUrl(byte[] postData) {
+ mPostData = postData;
+ }
+ @Override
+ public void run() {
+ awContents.loadUrl(LoadUrlParams.createLoadHttpPostParams(url,
+ mPostData));
+ }
+ }
+ runTestOnUiThread(new PostUrl(postData));
+ }
+
+ /**
* Loads data on the UI thread and blocks until onPageFinished is called.
*/
protected void loadDataSync(final AwContents awContents,
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientOnFormResubmissionTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientOnFormResubmissionTest.java
new file mode 100644
index 0000000..2e13880
--- /dev/null
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientOnFormResubmissionTest.java
@@ -0,0 +1,127 @@
+// Copyright (c) 2012 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.content.Context;
+import android.os.Message;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import org.apache.http.util.EncodingUtils;
+import org.chromium.android_webview.AwContents;
+import org.chromium.android_webview.test.util.TestWebServer;
+import org.chromium.base.test.util.Feature;
+import org.chromium.content.browser.ContentViewCore;
+import org.chromium.content.browser.test.util.TestCallbackHelperContainer;
+
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+/**
+ * Tests if resubmission of post data is handled properly.
+ */
+public class AwContentsClientOnFormResubmissionTest extends AndroidWebViewTestBase {
+
+ private static class TestAwContentsClient
+ extends org.chromium.android_webview.test.TestAwContentsClient {
+
+ // Number of times onFormResubmit is called.
+ private int mResubmissions = 0;
+ // Whether to resubmit Post data on reload.
+ private boolean mResubmit = false;
+
+ public int getResubmissions() {
+ return mResubmissions;
+ }
+ public void setResubmit(boolean resubmit) {
+ mResubmit = resubmit;
+ }
+ @Override
+ public void onFormResubmission(Message dontResend, Message resend) {
+ mResubmissions++;
+ if (mResubmit) {
+ resend.sendToTarget();
+ } else {
+ dontResend.sendToTarget();
+ }
+ }
+ }
+
+ // Server responses for load and reload of posts.
+ private final String LOAD_RESPONSE =
+ "<html><head><title>Load</title></head><body>HELLO</body></html>";
+ private final String RELOAD_RESPONSE =
+ "<html><head><title>Reload</title></head><body>HELLO</body></html>";
+
+ // Server timeout in seconds. Used to detect dontResend case.
+ private final int TIMEOUT = 3;
+
+ // The web server.
+ private TestWebServer mServer;
+ // The mock client.
+ private TestAwContentsClient mContentsClient;
+ private AwContents mAwContents;
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ mServer = new TestWebServer(false);
+ mContentsClient = new TestAwContentsClient();
+ final AwTestContainerView testContainerView =
+ createAwTestContainerViewOnMainSync(mContentsClient);
+ mAwContents = testContainerView.getAwContents();
+ }
+
+ @Override
+ public void tearDown() throws Exception {
+ mServer.shutdown();
+ super.tearDown();
+ }
+
+ @SmallTest
+ @Feature({"Android-WebView", "Navigation"})
+ public void testResend() throws Throwable {
+ mContentsClient.setResubmit(true);
+ doReload();
+ assertEquals(1, mContentsClient.getResubmissions());
+ assertEquals("Reload", getTitleOnUiThread(mAwContents));
+ }
+
+ @SmallTest
+ @Feature({"Android-WebView", "Navigation"})
+ public void testDontResend() throws Throwable {
+ mContentsClient.setResubmit(false);
+ doReload();
+ assertEquals(1, mContentsClient.getResubmissions());
+ assertEquals("Load", getTitleOnUiThread(mAwContents));
+ }
+
+ protected void doReload() throws Throwable {
+ String url = mServer.setResponse("/form", LOAD_RESPONSE, null);
+ String postData = "content=blabla";
+ byte[] data = EncodingUtils.getBytes(postData, "BASE64");
+ postUrlSync(mAwContents, mContentsClient.getOnPageFinishedHelper(), url, data);
+ assertEquals(0, mContentsClient.getResubmissions());
+ assertEquals("Load", getTitleOnUiThread(mAwContents));
+ // Verify reload works as expected.
+ mServer.setResponse("/form", RELOAD_RESPONSE, null);
+ TestCallbackHelperContainer.OnPageFinishedHelper onPageFinishedHelper =
+ mContentsClient.getOnPageFinishedHelper();
+ int callCount = onPageFinishedHelper.getCallCount();
+ // Run reload on UI thread.
+ getInstrumentation().runOnMainSync(new Runnable() {
+ @Override
+ public void run() {
+ mAwContents.getContentViewCore().reload();
+ }
+ });
+ try {
+ // Wait for page finished callback, or a timeout. A timeout is necessary
+ // to detect a dontResend response.
+ onPageFinishedHelper.waitForCallback(callCount, 1, TIMEOUT, TimeUnit.SECONDS);
+ } catch (TimeoutException e) {
+ }
+ }
+}
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/NullContentsClient.java b/android_webview/javatests/src/org/chromium/android_webview/test/NullContentsClient.java
index 2760c2d..594b322 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/NullContentsClient.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/NullContentsClient.java
@@ -5,6 +5,7 @@
package org.chromium.android_webview.test;
import android.content.Context;
+import android.os.Message;
import android.view.KeyEvent;
import android.webkit.ConsoleMessage;
@@ -84,4 +85,9 @@ class NullContentsClient extends AwContentsClient {
@Override
public void onReceivedError(int errorCode, String description, String failingUrl) {
}
+
+ @Override
+ public void onFormResubmission(Message dontResend, Message resend) {
+ dontResend.sendToTarget();
+ }
}
diff --git a/chrome/browser/component/web_contents_delegate_android/DEPS b/chrome/browser/component/web_contents_delegate_android/DEPS
index beaf5c3..2e11b18 100644
--- a/chrome/browser/component/web_contents_delegate_android/DEPS
+++ b/chrome/browser/component/web_contents_delegate_android/DEPS
@@ -1,3 +1,4 @@
include_rules = [
"+chrome/browser/component/web_contents_delegate_android",
+ "+content/public/android/java",
]
diff --git a/chrome/browser/component/web_contents_delegate_android/java/src/org/chromium/chrome/browser/component/web_contents_delegate_android/WebContentsDelegateAndroid.java b/chrome/browser/component/web_contents_delegate_android/java/src/org/chromium/chrome/browser/component/web_contents_delegate_android/WebContentsDelegateAndroid.java
index cee3cdf..be6934c 100644
--- a/chrome/browser/component/web_contents_delegate_android/java/src/org/chromium/chrome/browser/component/web_contents_delegate_android/WebContentsDelegateAndroid.java
+++ b/chrome/browser/component/web_contents_delegate_android/java/src/org/chromium/chrome/browser/component/web_contents_delegate_android/WebContentsDelegateAndroid.java
@@ -9,6 +9,7 @@ import android.view.KeyEvent;
import org.chromium.base.CalledByNative;
import org.chromium.base.JNINamespace;
+import org.chromium.content.browser.ContentViewCore;
/**
* Java peer of the native class of the same name.
@@ -106,4 +107,12 @@ public class WebContentsDelegateAndroid {
String sourceId) {
return false;
}
+
+ /**
+ * Report a form resubmission. The overwriter of this function should eventually call
+ * either of ContentViewCore.ContinuePendingReload or ContentViewCore.CancelPendingReload.
+ */
+ @CalledByNative
+ public void showRepostFormWarningDialog(ContentViewCore contentViewCore) {
+ }
}
diff --git a/chrome/browser/component/web_contents_delegate_android/web_contents_delegate_android.cc b/chrome/browser/component/web_contents_delegate_android/web_contents_delegate_android.cc
index 427f203..af997c4 100644
--- a/chrome/browser/component/web_contents_delegate_android/web_contents_delegate_android.cc
+++ b/chrome/browser/component/web_contents_delegate_android/web_contents_delegate_android.cc
@@ -8,6 +8,7 @@
#include "base/android/jni_android.h"
#include "base/android/jni_string.h"
+#include "content/public/browser/android/content_view_core.h"
#include "content/public/browser/render_widget_host_view.h"
#include "content/public/browser/invalidate_type.h"
#include "content/public/browser/page_navigator.h"
@@ -265,6 +266,20 @@ bool WebContentsDelegateAndroid::TakeFocus(WebContents* source, bool reverse) {
env, obj.obj(), reverse);
}
+void WebContentsDelegateAndroid::ShowRepostFormWarningDialog(
+ WebContents* source) {
+ JNIEnv* env = AttachCurrentThread();
+ ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env);
+ if (obj.is_null())
+ return;
+ ScopedJavaLocalRef<jobject> content_view_core =
+ content::ContentViewCore::FromWebContents(source)->GetJavaObject();
+ if (content_view_core.is_null())
+ return;
+ Java_WebContentsDelegateAndroid_showRepostFormWarningDialog(env, obj.obj(),
+ content_view_core.obj());
+}
+
// ----------------------------------------------------------------------------
// Native JNI methods
// ----------------------------------------------------------------------------
diff --git a/chrome/browser/component/web_contents_delegate_android/web_contents_delegate_android.gypi b/chrome/browser/component/web_contents_delegate_android/web_contents_delegate_android.gypi
index 922e802..23edd76 100644
--- a/chrome/browser/component/web_contents_delegate_android/web_contents_delegate_android.gypi
+++ b/chrome/browser/component/web_contents_delegate_android/web_contents_delegate_android.gypi
@@ -37,6 +37,7 @@
'type': 'none',
'dependencies': [
'<(DEPTH)/base/base.gyp:base',
+ '<(DEPTH)/content/content.gyp:content_java',
],
'variables': {
'package_name': 'web_contents_delegate_android',
diff --git a/chrome/browser/component/web_contents_delegate_android/web_contents_delegate_android.h b/chrome/browser/component/web_contents_delegate_android/web_contents_delegate_android.h
index 069aef7..52e0e25 100644
--- a/chrome/browser/component/web_contents_delegate_android/web_contents_delegate_android.h
+++ b/chrome/browser/component/web_contents_delegate_android/web_contents_delegate_android.h
@@ -90,6 +90,9 @@ class WebContentsDelegateAndroid : public content::WebContentsDelegate {
const content::NativeWebKeyboardEvent& event) OVERRIDE;
virtual bool TakeFocus(content::WebContents* source, bool reverse) OVERRIDE;
+ virtual void ShowRepostFormWarningDialog(
+ content::WebContents* source) OVERRIDE;
+
protected:
base::android::ScopedJavaLocalRef<jobject> GetJavaDelegate(JNIEnv* env) const;
diff --git a/content/browser/android/content_view_core_impl.cc b/content/browser/android/content_view_core_impl.cc
index e86d70d..9a88630 100644
--- a/content/browser/android/content_view_core_impl.cc
+++ b/content/browser/android/content_view_core_impl.cc
@@ -870,10 +870,18 @@ void ContentViewCoreImpl::StopLoading(JNIEnv* env, jobject obj) {
void ContentViewCoreImpl::Reload(JNIEnv* env, jobject obj) {
// Set check_for_repost parameter to false as we have no repost confirmation
// dialog ("confirm form resubmission" screen will still appear, however).
- web_contents_->GetController().Reload(false);
+ web_contents_->GetController().Reload(true);
tab_crashed_ = false;
}
+void ContentViewCoreImpl::CancelPendingReload(JNIEnv* env, jobject obj) {
+ web_contents_->GetController().CancelPendingReload();
+}
+
+void ContentViewCoreImpl::ContinuePendingReload(JNIEnv* env, jobject obj) {
+ web_contents_->GetController().ContinuePendingReload();
+}
+
void ContentViewCoreImpl::ClearHistory(JNIEnv* env, jobject obj) {
web_contents_->GetController().PruneAllButActive();
}
diff --git a/content/browser/android/content_view_core_impl.h b/content/browser/android/content_view_core_impl.h
index e2066a8..d5890f2 100644
--- a/content/browser/android/content_view_core_impl.h
+++ b/content/browser/android/content_view_core_impl.h
@@ -147,6 +147,8 @@ class ContentViewCoreImpl : public ContentViewCore,
void GoToOffset(JNIEnv* env, jobject obj, jint offset);
void StopLoading(JNIEnv* env, jobject obj);
void Reload(JNIEnv* env, jobject obj);
+ void CancelPendingReload(JNIEnv* env, jobject obj);
+ void ContinuePendingReload(JNIEnv* env, jobject obj);
jboolean NeedsReload(JNIEnv* env, jobject obj);
void ClearHistory(JNIEnv* env, jobject obj);
jint EvaluateJavaScript(JNIEnv* env, jobject obj, jstring script);
diff --git a/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java b/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java
index 1aadecd..a2c03b3 100644
--- a/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java
+++ b/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java
@@ -846,6 +846,20 @@ public class ContentViewCore implements MotionEventDelegate {
}
/**
+ * Cancel the pending reload.
+ */
+ public void cancelPendingReload() {
+ if (mNativeContentViewCore != 0) nativeCancelPendingReload(mNativeContentViewCore);
+ }
+
+ /**
+ * Continue the pending reload.
+ */
+ public void continuePendingReload() {
+ if (mNativeContentViewCore != 0) nativeContinuePendingReload(mNativeContentViewCore);
+ }
+
+ /**
* Clears the ContentViewCore's page history in both the backwards and
* forwards directions.
*/
@@ -2241,6 +2255,10 @@ public class ContentViewCore implements MotionEventDelegate {
private native void nativeReload(int nativeContentViewCoreImpl);
+ private native void nativeCancelPendingReload(int nativeContentViewCoreImpl);
+
+ private native void nativeContinuePendingReload(int nativeContentViewCoreImpl);
+
private native void nativeSelectPopupMenuItems(int nativeContentViewCoreImpl, int[] indices);
private native void nativeScrollFocusedEditableNodeIntoView(int nativeContentViewCoreImpl);