diff options
Diffstat (limited to 'android_webview')
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', |