summaryrefslogtreecommitdiffstats
path: root/android_webview
diff options
context:
space:
mode:
authoryfriedman@chromium.org <yfriedman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-09-20 19:28:39 +0000
committeryfriedman@chromium.org <yfriedman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-09-20 19:28:39 +0000
commit19fd5fa71955470f698bef815fabe2c1ac27f828 (patch)
treedf851a0604da9880f501835ae63e688b0901f4a8 /android_webview
parent18fb7a77d7bf1445bf6e68fa16a30e3ccc273847 (diff)
downloadchromium_src-19fd5fa71955470f698bef815fabe2c1ac27f828.zip
chromium_src-19fd5fa71955470f698bef815fabe2c1ac27f828.tar.gz
chromium_src-19fd5fa71955470f698bef815fabe2c1ac27f828.tar.bz2
Upstream chromium side of modal dialogs for webview.
There's still some default handling needed if the embedder doesn't override the handler. Includes clean-up of previous hooks in content that aren't needed anymore. BUG=138483 Review URL: https://chromiumcodereview.appspot.com/10907166 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@157815 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'android_webview')
-rw-r--r--android_webview/java/src/org/chromium/android_webview/AwContents.java21
-rw-r--r--android_webview/java/src/org/chromium/android_webview/AwContentsClient.java11
-rw-r--r--android_webview/java/src/org/chromium/android_webview/JsPromptResultReceiver.java17
-rw-r--r--android_webview/java/src/org/chromium/android_webview/JsResultHandler.java39
-rw-r--r--android_webview/java/src/org/chromium/android_webview/JsResultReceiver.java18
-rw-r--r--android_webview/javatests/src/org/chromium/android_webview/test/AndroidWebViewTestBase.java9
-rw-r--r--android_webview/javatests/src/org/chromium/android_webview/test/NullContentsClient.java22
-rw-r--r--android_webview/javatests/src/org/chromium/android_webview/test/WebViewModalDialogOverrideTest.java185
-rw-r--r--android_webview/native/android_webview_jni_registrar.cc2
-rw-r--r--android_webview/native/aw_browser_dependency_factory.h5
-rw-r--r--android_webview/native/aw_contents.cc60
-rw-r--r--android_webview/native/aw_contents.h13
-rw-r--r--android_webview/native/aw_javascript_dialog_creator.cc63
-rw-r--r--android_webview/native/aw_javascript_dialog_creator.h41
-rw-r--r--android_webview/native/aw_web_contents_delegate.cc11
-rw-r--r--android_webview/native/aw_web_contents_delegate.h2
-rw-r--r--android_webview/native/js_result_handler.cc48
-rw-r--r--android_webview/native/js_result_handler.h23
-rw-r--r--android_webview/native/webview_native.gyp5
19 files changed, 585 insertions, 10 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 c1e7947..3f826a9 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwContents.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwContents.java
@@ -233,6 +233,27 @@ public class AwContents {
return null;
}
+ @CalledByNative
+ private void handleJsAlert(String url, String message, JsResultReceiver receiver) {
+ mContentsClient.handleJsAlert(url, message, receiver);
+ }
+
+ @CalledByNative
+ private void handleJsBeforeUnload(String url, String message, JsResultReceiver receiver) {
+ mContentsClient.handleJsBeforeUnload(url, message, receiver);
+ }
+
+ @CalledByNative
+ private void handleJsConfirm(String url, String message, JsResultReceiver receiver) {
+ mContentsClient.handleJsConfirm(url, message, receiver);
+ }
+
+ @CalledByNative
+ private void handleJsPrompt(String url, String message, String defaultValue,
+ JsPromptResultReceiver receiver) {
+ mContentsClient.handleJsPrompt(url, message, defaultValue, receiver);
+ }
+
//--------------------------------------------------------------------------------------------
// Native methods
//--------------------------------------------------------------------------------------------
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 bcd0d19..4a4233d 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwContentsClient.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwContentsClient.java
@@ -33,7 +33,6 @@ public abstract class AwContentsClient extends ContentViewClient {
//--------------------------------------------------------------------------------------------
class WebContentsDelegateAdapter extends AwWebContentsDelegate {
-
@Override
public void onLoadProgressChanged(int progress) {
AwContentsClient.this.onProgressChanged(progress);
@@ -123,6 +122,16 @@ public abstract class AwContentsClient extends ContentViewClient {
public abstract void onReceivedHttpAuthRequest(AwHttpAuthHandler handler,
String host, String realm);
+ protected abstract void handleJsAlert(String url, String message, JsResultReceiver receiver);
+
+ protected abstract void handleJsBeforeUnload(String url, String message,
+ JsResultReceiver receiver);
+
+ protected abstract void handleJsConfirm(String url, String message, JsResultReceiver receiver);
+
+ protected abstract void handleJsPrompt(String url, String message, String defaultValue,
+ JsPromptResultReceiver receiver);
+
//--------------------------------------------------------------------------------------------
// Stuff that we ignore since it only makes sense for Chrome browser
//--------------------------------------------------------------------------------------------
diff --git a/android_webview/java/src/org/chromium/android_webview/JsPromptResultReceiver.java b/android_webview/java/src/org/chromium/android_webview/JsPromptResultReceiver.java
new file mode 100644
index 0000000..232140e
--- /dev/null
+++ b/android_webview/java/src/org/chromium/android_webview/JsPromptResultReceiver.java
@@ -0,0 +1,17 @@
+// 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;
+
+/**
+ * This interface is used when the AwContentsClient offers a JavaScript
+ * modal prompt dialog to enable the client to handle the dialog in their own way.
+ * AwContentsClient will offer an object that implements this interface to the
+ * client and when the client has handled the dialog, it must either callback with
+ * confirm() or cancel() to allow processing to continue.
+ */
+public interface JsPromptResultReceiver {
+ public void confirm(String result);
+ public void cancel();
+}
diff --git a/android_webview/java/src/org/chromium/android_webview/JsResultHandler.java b/android_webview/java/src/org/chromium/android_webview/JsResultHandler.java
new file mode 100644
index 0000000..3720324
--- /dev/null
+++ b/android_webview/java/src/org/chromium/android_webview/JsResultHandler.java
@@ -0,0 +1,39 @@
+// 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;
+import org.chromium.base.CalledByNative;
+import org.chromium.base.JNINamespace;
+
+@JNINamespace("android_webview")
+public class JsResultHandler implements JsResultReceiver, JsPromptResultReceiver {
+ private int mNativeDialogPointer;
+
+ @CalledByNative
+ public static JsResultHandler create(int nativeDialogPointer) {
+ return new JsResultHandler(nativeDialogPointer);
+ }
+
+ private JsResultHandler(int nativeDialogPointer) {
+ mNativeDialogPointer = nativeDialogPointer;
+ }
+
+ @Override
+ public void confirm() {
+ confirm(null);
+ }
+
+ @Override
+ public void confirm(String promptResult) {
+ nativeConfirmJsResult(mNativeDialogPointer, promptResult);
+ }
+
+ @Override
+ public void cancel() {
+ nativeCancelJsResult(mNativeDialogPointer);
+ }
+
+ private native void nativeConfirmJsResult(int dialogPointer, String promptResult);
+ private native void nativeCancelJsResult(int dialogPointer);
+}
diff --git a/android_webview/java/src/org/chromium/android_webview/JsResultReceiver.java b/android_webview/java/src/org/chromium/android_webview/JsResultReceiver.java
new file mode 100644
index 0000000..30df245
--- /dev/null
+++ b/android_webview/java/src/org/chromium/android_webview/JsResultReceiver.java
@@ -0,0 +1,18 @@
+// 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;
+
+/**
+ * This interface is used when the AwContentsClient offers a JavaScript
+ * modal dialog (alert, beforeunload or confirm) to enable the client to
+ * handle the dialog in their own way. AwContentsClient will offer an object
+ * that implements this interface to the client and when the client has handled
+ * the dialog, it must either callback with confirm() or cancel() to allow
+ * processing to continue.
+ */
+public interface JsResultReceiver {
+ public void confirm();
+ public void cancel();
+}
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 3ba898b..3b246fc 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
@@ -80,6 +80,15 @@ public class AndroidWebViewTestBase
}
}
+ protected void enableJavaScriptOnUiThread(final ContentViewCore contentViewCore) {
+ getInstrumentation().runOnMainSync(new Runnable() {
+ @Override
+ public void run() {
+ contentViewCore.getContentSettings().setJavaScriptEnabled(true);
+ }
+ });
+ }
+
/**
* Loads url on the UI thread and blocks until onPageFinished is called.
*/
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 630efe2..bd1809c 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
@@ -4,11 +4,14 @@
package org.chromium.android_webview.test;
+import android.content.Context;
import android.view.KeyEvent;
import android.webkit.ConsoleMessage;
import org.chromium.android_webview.AwContentsClient;
import org.chromium.android_webview.AwHttpAuthHandler;
+import org.chromium.android_webview.JsPromptResultReceiver;
+import org.chromium.android_webview.JsResultReceiver;
/**
* As a convience for tests that only care about specefic callbacks, this class provides
@@ -37,4 +40,21 @@ class NullContentsClient extends AwContentsClient {
public void onReceivedHttpAuthRequest(AwHttpAuthHandler handler, String host, String realm) {
handler.cancel();
}
-};
+
+ @Override
+ public void handleJsAlert(String url, String message, JsResultReceiver receiver) {
+ }
+
+ @Override
+ public void handleJsBeforeUnload(String url, String message, JsResultReceiver receiver) {
+ }
+
+ @Override
+ public void handleJsConfirm(String url, String message, JsResultReceiver receiver) {
+ }
+
+ @Override
+ public void handleJsPrompt(
+ String url, String message, String defaultValue, JsPromptResultReceiver receiver) {
+ }
+}
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/WebViewModalDialogOverrideTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/WebViewModalDialogOverrideTest.java
new file mode 100644
index 0000000..473f8f1
--- /dev/null
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/WebViewModalDialogOverrideTest.java
@@ -0,0 +1,185 @@
+// 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.
+
+/**
+ * Test suite for displaying and functioning of modal dialogs.
+ */
+
+package org.chromium.android_webview.test;
+
+import android.test.suitebuilder.annotation.MediumTest;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import junit.framework.Assert;
+
+import org.chromium.android_webview.JsPromptResultReceiver;
+import org.chromium.android_webview.JsResultReceiver;
+import org.chromium.base.test.Feature;
+import org.chromium.content.browser.ContentViewCore;
+import org.chromium.content.browser.util.CallbackHelper;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+
+public class WebViewModalDialogOverrideTest extends AndroidWebViewTestBase {
+ private final static String EMPTY_PAGE =
+ "<!doctype html>" +
+ "<title>Modal Dialog Test</title><p>Testcase.</p>";
+ private final static String BEFORE_UNLOAD_URL =
+ "<!doctype html>" +
+ "<head><script>window.onbeforeunload=function() {" +
+ "return 'Are you sure?';" +
+ "};</script></head></body>";
+
+ /*
+ * Verify that when the AwContentsClient calls handleJsAlert.
+ */
+ @SmallTest
+ @Feature({"Android-WebView"})
+ public void testOverrideAlertHandling() throws Throwable {
+ final String ALERT_TEXT = "Hello World!";
+
+ final AtomicBoolean callbackCalled = new AtomicBoolean(false);
+ // Returning true from the callback should not show a dialog.
+ TestAwContentsClient client = new TestAwContentsClient() {
+ @Override
+ public void handleJsAlert(String url, String message, JsResultReceiver res) {
+ callbackCalled.set(true);
+ res.confirm();
+ assertEquals(ALERT_TEXT, message);
+ }
+ };
+ AwTestContainerView view = createAwTestContainerViewOnMainSync(client);
+ final ContentViewCore contentViewCore = view.getContentViewCore();
+
+ enableJavaScriptOnUiThread(contentViewCore);
+ loadDataSync(contentViewCore, client.getOnPageFinishedHelper(),
+ EMPTY_PAGE, "text/html", false);
+ executeJavaScriptAndWaitForResult(contentViewCore, client,
+ "alert('" + ALERT_TEXT + "')");
+ assertTrue(callbackCalled.get());
+ }
+
+ /*
+ * Verify that when the AwContentsClient calls handleJsPrompt.
+ */
+ @SmallTest
+ @Feature({"Android-WebView"})
+ public void testOverridePromptHandling() throws Throwable {
+ final String PROMPT_TEXT = "How do you like your eggs in the morning?";
+ final String PROMPT_DEFAULT = "Scrambled";
+ final String PROMPT_RESULT = "I like mine with a kiss";
+
+ final AtomicBoolean called = new AtomicBoolean(false);
+ // Returning true from the callback should not show a dialog.
+ final TestAwContentsClient client = new TestAwContentsClient() {
+ @Override
+ public void handleJsPrompt(String url, String message, String defaultValue,
+ JsPromptResultReceiver res) {
+ assertEquals(PROMPT_TEXT, message);
+ assertEquals(PROMPT_DEFAULT, defaultValue);
+ res.confirm(PROMPT_RESULT);
+ called.set(true);
+ }
+ };
+ AwTestContainerView view = createAwTestContainerViewOnMainSync(client);
+ ContentViewCore contentViewCore = view.getContentViewCore();
+
+ enableJavaScriptOnUiThread(contentViewCore);
+ loadDataSync(contentViewCore, client.getOnPageFinishedHelper(),
+ EMPTY_PAGE, "text/html", false);
+ String result = executeJavaScriptAndWaitForResult(contentViewCore, client,
+ "prompt('" + PROMPT_TEXT + "','" + PROMPT_DEFAULT + "')");
+ assertTrue(called.get());
+ assertEquals("\"" + PROMPT_RESULT + "\"", result);
+ }
+
+ /*
+ * Verify that when the AwContentsClient calls handleJsConfirm and the client confirms.
+ */
+ @SmallTest
+ @Feature({"Android-WebView"})
+ public void testOverrideConfirmHandlingConfirmed() throws Throwable {
+ final String CONFIRM_TEXT = "Would you like a cookie?";
+
+ final AtomicBoolean called = new AtomicBoolean(false);
+ // Returning true from the callback should not show a dialog.
+ TestAwContentsClient client = new TestAwContentsClient() {
+ @Override
+ public void handleJsConfirm(String url, String message, JsResultReceiver res) {
+ assertEquals(CONFIRM_TEXT, message);
+ res.confirm();
+ called.set(true);
+ }
+ };
+ AwTestContainerView view = createAwTestContainerViewOnMainSync(client);
+ ContentViewCore contentViewCore = view.getContentViewCore();
+ enableJavaScriptOnUiThread(contentViewCore);
+
+ loadDataSync(contentViewCore, client.getOnPageFinishedHelper(),
+ EMPTY_PAGE, "text/html", false);
+ String result = executeJavaScriptAndWaitForResult(contentViewCore, client,
+ "confirm('" + CONFIRM_TEXT + "')");
+ assertTrue(called.get());
+ assertEquals("true", result);
+ }
+
+ /*
+ * Verify that when the AwContentsClient calls handleJsConfirm and the client cancels.
+ */
+ @SmallTest
+ @Feature({"Android-WebView"})
+ public void testOverrideConfirmHandlingCancelled() throws Throwable {
+ final String CONFIRM_TEXT = "Would you like a cookie?";
+
+ final AtomicBoolean called = new AtomicBoolean(false);
+ // Returning true from the callback should not show a dialog.
+ TestAwContentsClient client = new TestAwContentsClient() {
+ @Override
+ public void handleJsConfirm(String url, String message, JsResultReceiver res) {
+ assertEquals(CONFIRM_TEXT, message);
+ res.cancel();
+ called.set(true);
+ }
+ };
+ AwTestContainerView view = createAwTestContainerViewOnMainSync(client);
+ ContentViewCore contentViewCore = view.getContentViewCore();
+ enableJavaScriptOnUiThread(contentViewCore);
+
+ loadDataSync(contentViewCore, client.getOnPageFinishedHelper(),
+ EMPTY_PAGE, "text/html", false);
+ String result = executeJavaScriptAndWaitForResult(contentViewCore, client,
+ "confirm('" + CONFIRM_TEXT + "')");
+ assertTrue(called.get());
+ assertEquals("false", result);
+ }
+
+ /*
+ * Verify that when the AwContentsClient calls handleJsBeforeUnload
+ */
+ @MediumTest
+ @Feature({"Android-WebView"})
+ public void testOverrideBeforeUnloadHandling() throws Throwable {
+ final CallbackHelper jsBeforeUnloadHelper = new CallbackHelper();
+ TestAwContentsClient client = new TestAwContentsClient() {
+ @Override
+ public void handleJsBeforeUnload(String url, String message, JsResultReceiver res) {
+ res.cancel();
+ jsBeforeUnloadHelper.notifyCalled();
+ }
+ };
+ AwTestContainerView view = createAwTestContainerViewOnMainSync(client);
+ ContentViewCore contentViewCore = view.getContentViewCore();
+ enableJavaScriptOnUiThread(contentViewCore);
+
+ loadDataSync(contentViewCore, client.getOnPageFinishedHelper(), BEFORE_UNLOAD_URL,
+ "text/html", false);
+ enableJavaScriptOnUiThread(contentViewCore);
+
+ // Don't wait synchronously because we don't leave the page.
+ int currentCallCount = jsBeforeUnloadHelper.getCallCount();
+ loadDataAsync(contentViewCore, EMPTY_PAGE, "text/html", false);
+ jsBeforeUnloadHelper.waitForCallback(currentCallCount);
+ }
+}
diff --git a/android_webview/native/android_webview_jni_registrar.cc b/android_webview/native/android_webview_jni_registrar.cc
index 6b62267..ba497db 100644
--- a/android_webview/native/android_webview_jni_registrar.cc
+++ b/android_webview/native/android_webview_jni_registrar.cc
@@ -9,6 +9,7 @@
#include "android_webview/native/aw_contents_io_thread_client.h"
#include "android_webview/native/aw_http_auth_handler.h"
#include "android_webview/native/cookie_manager.h"
+#include "android_webview/native/js_result_handler.h"
#include "base/android/jni_android.h"
#include "base/android/jni_registrar.h"
#include "chrome/browser/component/web_contents_delegate_android/component_jni_registrar.h"
@@ -21,6 +22,7 @@ static base::android::RegistrationMethod kWebViewRegisteredMethods[] = {
{ "AwContentsIoThreadClient", RegisterAwContentsIoThreadClient},
{ "AwHttpAuthHandler", RegisterAwHttpAuthHandler },
{ "CookieManager", RegisterCookieManager },
+ { "JsResultHandler", RegisterJsResultHandler },
};
bool RegisterJni(JNIEnv* env) {
diff --git a/android_webview/native/aw_browser_dependency_factory.h b/android_webview/native/aw_browser_dependency_factory.h
index 7914069..43ca618 100644
--- a/android_webview/native/aw_browser_dependency_factory.h
+++ b/android_webview/native/aw_browser_dependency_factory.h
@@ -47,10 +47,6 @@ class AwBrowserDependencyFactory {
virtual AwContentsContainer* CreateContentsContainer(
content::WebContents* contents) = 0;
- // As per the WebContentsDelegate method of the same name. Ownership is NOT
- // returned; the instance must be long-lived.
- virtual content::JavaScriptDialogCreator* GetJavaScriptDialogCreator() = 0;
-
protected:
AwBrowserDependencyFactory();
@@ -61,4 +57,3 @@ class AwBrowserDependencyFactory {
} // namespace android_webview
#endif // ANDROID_WEBVIEW_AW_BROWSER_DELEGATE_H_
-
diff --git a/android_webview/native/aw_contents.cc b/android_webview/native/aw_contents.cc
index 4b21b58..fab4809 100644
--- a/android_webview/native/aw_contents.cc
+++ b/android_webview/native/aw_contents.cc
@@ -20,8 +20,8 @@
#include "jni/AwContents_jni.h"
using base::android::AttachCurrentThread;
-using base::android::ConvertUTF8ToJavaString;
using base::android::ConvertUTF16ToJavaString;
+using base::android::ConvertUTF8ToJavaString;
using base::android::ScopedJavaGlobalRef;
using base::android::ScopedJavaLocalRef;
using content::BrowserThread;
@@ -69,8 +69,6 @@ AwContents::AwContents(JNIEnv* env,
contents_container_.reset(dependency_factory->CreateContentsContainer(
web_contents));
web_contents->SetDelegate(web_contents_delegate_.get());
- web_contents_delegate_->SetJavaScriptDialogCreator(
- dependency_factory->GetJavaScriptDialogCreator());
web_contents->SetUserData(kAwContentsUserDataKey,
new AwContentsUserData(this));
render_view_host_ext_.reset(new AwRenderViewHostExt(web_contents));
@@ -129,6 +127,62 @@ void AwContents::GenerateMHTML(JNIEnv* env, jobject obj,
base::Bind(&GenerateMHTMLCallback, base::Owned(j_callback)));
}
+void AwContents::RunJavaScriptDialog(
+ content::JavaScriptMessageType message_type,
+ const GURL& origin_url,
+ const string16& message_text,
+ const string16& default_prompt_text,
+ const base::android::ScopedJavaLocalRef<jobject>& js_result) {
+ JNIEnv* env = base::android::AttachCurrentThread();
+
+ ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
+ if (obj.is_null())
+ return;
+
+ ScopedJavaLocalRef<jstring> jurl(ConvertUTF8ToJavaString(
+ env, origin_url.spec()));
+ ScopedJavaLocalRef<jstring> jmessage(ConvertUTF16ToJavaString(
+ env, message_text));
+ switch (message_type) {
+ case content::JAVASCRIPT_MESSAGE_TYPE_ALERT:
+ Java_AwContents_handleJsAlert(
+ env, obj.obj(), jurl.obj(), jmessage.obj(), js_result.obj());
+ break;
+ case content::JAVASCRIPT_MESSAGE_TYPE_CONFIRM:
+ Java_AwContents_handleJsConfirm(
+ env, obj.obj(), jurl.obj(), jmessage.obj(), js_result.obj());
+ break;
+ case content::JAVASCRIPT_MESSAGE_TYPE_PROMPT: {
+ ScopedJavaLocalRef<jstring> jdefault_value(
+ ConvertUTF16ToJavaString(env, default_prompt_text));
+ Java_AwContents_handleJsPrompt(
+ env, obj.obj(), jurl.obj(), jmessage.obj(),
+ jdefault_value.obj(), js_result.obj());
+ break;
+ }
+ default:
+ NOTREACHED();
+ }
+}
+
+void AwContents::RunBeforeUnloadDialog(
+ const GURL& origin_url,
+ const string16& message_text,
+ const base::android::ScopedJavaLocalRef<jobject>& js_result) {
+ JNIEnv* env = base::android::AttachCurrentThread();
+
+ ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
+ if (obj.is_null())
+ return;
+
+ ScopedJavaLocalRef<jstring> jurl(ConvertUTF8ToJavaString(
+ env, origin_url.spec()));
+ ScopedJavaLocalRef<jstring> jmessage(ConvertUTF16ToJavaString(
+ env, message_text));
+ Java_AwContents_handleJsBeforeUnload(
+ env, obj.obj(), jurl.obj(), jmessage.obj(), js_result.obj());
+}
+
void AwContents::onReceivedHttpAuthRequest(
const base::android::JavaRef<jobject>& handler,
const std::string& host,
diff --git a/android_webview/native/aw_contents.h b/android_webview/native/aw_contents.h
index e441bd1..472075e 100644
--- a/android_webview/native/aw_contents.h
+++ b/android_webview/native/aw_contents.h
@@ -11,6 +11,7 @@
#include "base/android/scoped_java_ref.h"
#include "base/android/jni_helper.h"
#include "base/memory/scoped_ptr.h"
+#include "content/public/browser/javascript_dialogs.h"
class TabContents;
@@ -39,6 +40,18 @@ class AwContents {
bool private_browsing);
~AwContents();
+ void RunJavaScriptDialog(
+ content::JavaScriptMessageType message_type,
+ const GURL& origin_url,
+ const string16& message_text,
+ const string16& default_prompt_text,
+ const base::android::ScopedJavaLocalRef<jobject>& js_result);
+
+ void RunBeforeUnloadDialog(
+ const GURL& origin_url,
+ const string16& message_text,
+ const base::android::ScopedJavaLocalRef<jobject>& js_result);
+
// |handler| is an instance of
// org.chromium.android_webview.AwHttpAuthHandler.
void onReceivedHttpAuthRequest(const base::android::JavaRef<jobject>& handler,
diff --git a/android_webview/native/aw_javascript_dialog_creator.cc b/android_webview/native/aw_javascript_dialog_creator.cc
new file mode 100644
index 0000000..bf3e1b3
--- /dev/null
+++ b/android_webview/native/aw_javascript_dialog_creator.cc
@@ -0,0 +1,63 @@
+// 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.
+
+#include "android_webview/native/aw_javascript_dialog_creator.h"
+
+#include "android_webview/native/aw_contents.h"
+#include "android_webview/native/js_result_handler.h"
+#include "base/android/jni_android.h"
+#include "base/android/jni_helper.h"
+#include "base/android/jni_string.h"
+#include "base/android/scoped_java_ref.h"
+#include "base/logging.h"
+#include "base/string16.h"
+#include "content/public/browser/javascript_dialogs.h"
+#include "content/public/browser/web_contents.h"
+
+using base::android::AttachCurrentThread;
+using base::android::ScopedJavaLocalRef;
+
+namespace android_webview {
+
+AwJavaScriptDialogCreator::AwJavaScriptDialogCreator() {}
+
+AwJavaScriptDialogCreator::~AwJavaScriptDialogCreator() {}
+
+void AwJavaScriptDialogCreator::RunJavaScriptDialog(
+ content::WebContents* web_contents,
+ const GURL& origin_url,
+ const std::string& accept_lang,
+ content::JavaScriptMessageType message_type,
+ const string16& message_text,
+ const string16& default_prompt_text,
+ const DialogClosedCallback& callback,
+ bool* did_suppress_message) {
+ JNIEnv* env = AttachCurrentThread();
+ ScopedJavaLocalRef<jobject> js_result = createJsResultHandler(
+ env,
+ &callback);
+ AwContents* contents = AwContents::FromWebContents(web_contents);
+ contents->RunJavaScriptDialog(message_type, origin_url, message_text,
+ default_prompt_text, js_result);
+}
+
+void AwJavaScriptDialogCreator::RunBeforeUnloadDialog(
+ content::WebContents* web_contents,
+ const string16& message_text,
+ bool is_reload,
+ const DialogClosedCallback& callback) {
+ JNIEnv* env = AttachCurrentThread();
+ ScopedJavaLocalRef<jobject> js_result = createJsResultHandler(
+ env,
+ &callback);
+ AwContents* contents = AwContents::FromWebContents(web_contents);
+ contents->RunBeforeUnloadDialog(web_contents->GetURL(), message_text,
+ js_result);
+}
+
+void AwJavaScriptDialogCreator::ResetJavaScriptState(
+ content::WebContents* web_contents) {
+}
+
+} // namespace android_webview
diff --git a/android_webview/native/aw_javascript_dialog_creator.h b/android_webview/native/aw_javascript_dialog_creator.h
new file mode 100644
index 0000000..9c5f9a5
--- /dev/null
+++ b/android_webview/native/aw_javascript_dialog_creator.h
@@ -0,0 +1,41 @@
+// 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.
+
+#ifndef ANDROID_WEBVIEW_NATIVE_AW_JAVASCRIPT_DIALOG_CREATOR_H_
+#define ANDROID_WEBVIEW_NATIVE_AW_JAVASCRIPT_DIALOG_CREATOR_H_
+
+#include "content/public/browser/javascript_dialogs.h"
+
+namespace android_webview {
+
+class AwJavaScriptDialogCreator : public content::JavaScriptDialogCreator {
+ public:
+ explicit AwJavaScriptDialogCreator();
+ virtual ~AwJavaScriptDialogCreator();
+
+ // Overridden from content::JavaScriptDialogCreator:
+ virtual void RunJavaScriptDialog(
+ content::WebContents* web_contents,
+ const GURL& origin_url,
+ const std::string& accept_lang,
+ content::JavaScriptMessageType message_type,
+ const string16& message_text,
+ const string16& default_prompt_text,
+ const DialogClosedCallback& callback,
+ bool* did_suppress_message) OVERRIDE;
+ virtual void RunBeforeUnloadDialog(
+ content::WebContents* web_contents,
+ const string16& message_text,
+ bool is_reload,
+ const DialogClosedCallback& callback) OVERRIDE;
+ virtual void ResetJavaScriptState(
+ content::WebContents* web_contents) OVERRIDE;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(AwJavaScriptDialogCreator);
+};
+
+} // namespace android_webview
+
+#endif // ANDROID_WEBVIEW_NATIVE_AW_JAVASCRIPT_DIALOG_CREATOR_H_
diff --git a/android_webview/native/aw_web_contents_delegate.cc b/android_webview/native/aw_web_contents_delegate.cc
index 7302128..249ee0f 100644
--- a/android_webview/native/aw_web_contents_delegate.cc
+++ b/android_webview/native/aw_web_contents_delegate.cc
@@ -4,8 +4,14 @@
#include "android_webview/native/aw_web_contents_delegate.h"
+#include "base/lazy_instance.h"
+#include "android_webview/native/aw_javascript_dialog_creator.h"
+
namespace android_webview {
+static base::LazyInstance<AwJavaScriptDialogCreator>::Leaky
+ g_javascript_dialog_creator = LAZY_INSTANCE_INITIALIZER;
+
AwWebContentsDelegate::AwWebContentsDelegate(
JNIEnv* env,
jobject obj)
@@ -15,4 +21,9 @@ AwWebContentsDelegate::AwWebContentsDelegate(
AwWebContentsDelegate::~AwWebContentsDelegate() {
}
+content::JavaScriptDialogCreator*
+AwWebContentsDelegate::GetJavaScriptDialogCreator() {
+ return g_javascript_dialog_creator.Pointer();
+}
+
} // namespace android_webview
diff --git a/android_webview/native/aw_web_contents_delegate.h b/android_webview/native/aw_web_contents_delegate.h
index add2052..011451e 100644
--- a/android_webview/native/aw_web_contents_delegate.h
+++ b/android_webview/native/aw_web_contents_delegate.h
@@ -19,6 +19,8 @@ class AwWebContentsDelegate
public:
AwWebContentsDelegate(JNIEnv* env, jobject obj);
virtual ~AwWebContentsDelegate();
+ virtual content::JavaScriptDialogCreator* GetJavaScriptDialogCreator()
+ OVERRIDE;
};
} // namespace android_webview
diff --git a/android_webview/native/js_result_handler.cc b/android_webview/native/js_result_handler.cc
new file mode 100644
index 0000000..56d57dc
--- /dev/null
+++ b/android_webview/native/js_result_handler.cc
@@ -0,0 +1,48 @@
+// 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.
+
+#include "android_webview/native/js_result_handler.h"
+
+#include "base/android/jni_string.h"
+#include "jni/JsResultHandler_jni.h"
+#include "content/public/browser/javascript_dialogs.h"
+#include "content/public/browser/android/content_view_core.h"
+
+using base::android::ConvertJavaStringToUTF16;
+using content::ContentViewCore;
+
+namespace android_webview {
+
+void ConfirmJsResult(JNIEnv* env,
+ jobject obj,
+ jint dialogPointer,
+ jstring promptResult) {
+ content::JavaScriptDialogCreator::DialogClosedCallback* dialog_ =
+ reinterpret_cast<content::JavaScriptDialogCreator::DialogClosedCallback*>(
+ dialogPointer);
+ string16 prompt_text;
+ if (promptResult) {
+ prompt_text = ConvertJavaStringToUTF16(env, promptResult);
+ }
+ dialog_->Run(true,prompt_text);
+}
+
+void CancelJsResult(JNIEnv* env, jobject obj, jint dialogPointer) {
+ content::JavaScriptDialogCreator::DialogClosedCallback* dialog_ =
+ reinterpret_cast<content::JavaScriptDialogCreator::DialogClosedCallback*>(
+ dialogPointer);
+ dialog_->Run(false, string16());
+}
+
+base::android::ScopedJavaLocalRef<jobject> createJsResultHandler(
+ JNIEnv* env,
+ const content::JavaScriptDialogCreator::DialogClosedCallback* dialog) {
+ return Java_JsResultHandler_create(env, reinterpret_cast<jint>(dialog));
+}
+
+bool RegisterJsResultHandler(JNIEnv* env) {
+ return RegisterNativesImpl(env);
+}
+
+} // namespace android_webview
diff --git a/android_webview/native/js_result_handler.h b/android_webview/native/js_result_handler.h
new file mode 100644
index 0000000..c85b116
--- /dev/null
+++ b/android_webview/native/js_result_handler.h
@@ -0,0 +1,23 @@
+// 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.
+
+#ifndef ANDROID_WEBVIEW_NATIVE_JS_RESULT_HANDLER_H_
+#define ANDROID_WEBVIEW_NATIVE_JS_RESULT_HANDLER_H_
+
+#include "base/android/jni_helper.h"
+#include "base/android/scoped_java_ref.h"
+#include "content/public/browser/javascript_dialogs.h"
+
+namespace android_webview {
+
+bool RegisterJsResultHandler(JNIEnv* env);
+
+base::android::ScopedJavaLocalRef<jobject> createJsResultHandler(
+ JNIEnv* env,
+ const content::JavaScriptDialogCreator::DialogClosedCallback*
+ native_dialog_pointer);
+
+} // namespace android_webview
+
+#endif // ANDROID_WEBVIEW_NATIVE_JS_RESULT_HANDLER_H_
diff --git a/android_webview/native/webview_native.gyp b/android_webview/native/webview_native.gyp
index 1eb7bb6..83a537f 100644
--- a/android_webview/native/webview_native.gyp
+++ b/android_webview/native/webview_native.gyp
@@ -33,12 +33,16 @@
'aw_contents_io_thread_client.h',
'aw_http_auth_handler.cc',
'aw_http_auth_handler.h',
+ 'aw_javascript_dialog_creator.cc',
+ 'aw_javascript_dialog_creator.h',
'aw_web_contents_delegate.cc',
'aw_web_contents_delegate.h',
'cookie_manager.cc',
'cookie_manager.h',
'intercepted_request_data.cc',
'intercepted_request_data.h',
+ 'js_result_handler.cc',
+ 'js_result_handler.h',
],
},
{
@@ -51,6 +55,7 @@
'../java/src/org/chromium/android_webview/AwHttpAuthHandler.java',
'../java/src/org/chromium/android_webview/CookieManager.java',
'../java/src/org/chromium/android_webview/InterceptedRequestData.java',
+ '../java/src/org/chromium/android_webview/JsResultHandler.java',
],
'variables': {
'jni_gen_dir': 'android_webview',