diff options
author | leandrogracia@chromium.org <leandrogracia@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-08-21 18:28:30 +0000 |
---|---|---|
committer | leandrogracia@chromium.org <leandrogracia@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-08-21 18:28:30 +0000 |
commit | f1c3c7977af93d1421db66d39ea83b9aa97747e2 (patch) | |
tree | 80a97f67fc5aa7490705628333fe2f8088f36c56 | |
parent | a9b4441d02e85aac508fc2707b9f2cbde142421b (diff) | |
download | chromium_src-f1c3c7977af93d1421db66d39ea83b9aa97747e2.zip chromium_src-f1c3c7977af93d1421db66d39ea83b9aa97747e2.tar.gz chromium_src-f1c3c7977af93d1421db66d39ea83b9aa97747e2.tar.bz2 |
Refactor the Android port to allow access to the chrome layer.
While in desktop chrome the main WebContentsDelegate is implemented in the
chrome layer by the Browser class, the Android port implements it in the
content layer in its ContentViewClient class. However, because of the content
layering limitations this renders the chrome layer out of reach.
This patch splits the WebContentsDelegate implementation in ContentViewClient
into a separate class named WebContentsDelegateAndroid in the first chrome browser component "web_contents_delegate_android".
Also, this patch introduces stubs for Chrome-specific and WebView-specific extensions of WebContentsDelegateAndroid in order to set the foundations for later patches.
BUG=137967
TEST=existing tests
Review URL: https://chromiumcodereview.appspot.com/10831060
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@152598 0039d316-1c4b-4281-b951-d872f2087c98
44 files changed, 1142 insertions, 769 deletions
diff --git a/android_webview/DEPS b/android_webview/DEPS index ea141dc..ed3891d 100644 --- a/android_webview/DEPS +++ b/android_webview/DEPS @@ -6,5 +6,7 @@ # chrome/ should go into android_webview/lib/ or be refactored. include_rules = [ + "+chrome/android/java/src/org/chromium/chrome/browser/component", + "+chrome/browser/component", "+content/public", ] diff --git a/android_webview/build/install_binary b/android_webview/build/install_binary new file mode 100755 index 0000000..24aaa83 --- /dev/null +++ b/android_webview/build/install_binary @@ -0,0 +1,23 @@ +#!/bin/bash -x +# 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. + +# Copies a possibly stripped binary and a symbol file to installation dirs. + +if [ "$3" = "" ] +then + echo "Usage: install_binary path/to/binary path/to/target1 path/to/target2 path/to/symbols" + exit 1 +fi + +SOURCE=$1 +TARGET=$2 +TARGET2=$3 +SYMBOLS=$4 + +mkdir -p $(dirname $SYMBOLS) + +cp $SOURCE $SYMBOLS +$STRIP --strip-unneeded $SOURCE -o $TARGET +cp $TARGET $TARGET2 diff --git a/android_webview/java/src/org/chromium/android_webview/AwWebContentsDelegate.java b/android_webview/java/src/org/chromium/android_webview/AwWebContentsDelegate.java new file mode 100644 index 0000000..207f396 --- /dev/null +++ b/android_webview/java/src/org/chromium/android_webview/AwWebContentsDelegate.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; + +import org.chromium.base.JNINamespace; +import org.chromium.chrome.browser.component.web_contents_delegate_android.WebContentsDelegateAndroid; + +/** + * WebView-specific WebContentsDelegate. + * This file is the Java version of the native class of the same name. + * It should contain empty WebContentsDelegate methods to be implemented by the embedder. + * These methods belong to WebView but are not shared with the Chromium Android port. + */ +@JNINamespace("android_webview") +public class AwWebContentsDelegate extends WebContentsDelegateAndroid { +} diff --git a/android_webview/lib/android_webview.gyp b/android_webview/lib/android_webview.gyp index 353e6bf..8cd34ee 100644 --- a/android_webview/lib/android_webview.gyp +++ b/android_webview/lib/android_webview.gyp @@ -13,9 +13,11 @@ '../../chrome/chrome.gyp:browser', '../../chrome/chrome.gyp:renderer', '../../content/content.gyp:content', + '../native/webview_native.gyp:webview_native', ], 'include_dirs': [ '../..', + '../../skia/config', ], 'sources': [ 'main/webview_entry_point.cc', @@ -24,6 +26,34 @@ 'main/webview_stubs.cc', ], }, + { + 'target_name': 'android_webview', + 'type' : 'none', + 'dependencies': [ + 'libwebview', + ], + 'variables': { + 'install_binary_script': '../build/install_binary', + }, + 'actions': [ + { + 'action_name': 'libwebview_strip_and_install_in_android', + 'inputs': [ + '<(SHARED_LIB_DIR)/libwebview.so', + ], + 'outputs': [ + '<(android_product_out)/obj/lib/libwebview.so', + '<(android_product_out)/system/lib/libwebview.so', + '<(android_product_out)/symbols/system/lib/libwebview.so', + ], + 'action': [ + '<(install_binary_script)', + '<@(_inputs)', + '<@(_outputs)', + ], + }, + ], + }, ], } diff --git a/android_webview/lib/main/webview_entry_point.cc b/android_webview/lib/main/webview_entry_point.cc index 04a52df..2053910 100644 --- a/android_webview/lib/main/webview_entry_point.cc +++ b/android_webview/lib/main/webview_entry_point.cc @@ -3,6 +3,7 @@ // found in the LICENSE file. #include "android_webview/lib/main/webview_main_delegate.h" +#include "android_webview/native/android_webview_jni_registrar.h" #include "base/android/jni_android.h" #include "content/public/app/android_library_loader_hooks.h" #include "content/public/app/content_main.h" @@ -12,9 +13,11 @@ JNI_EXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) { base::android::InitVM(vm); JNIEnv* env = base::android::AttachCurrentThread(); - if (!content::RegisterLibraryLoaderEntryHook(env)) { + if (!content::RegisterLibraryLoaderEntryHook(env)) + return -1; + + if (!android_webview::RegisterJni(env)) return -1; - } content::SetContentMainDelegate(new android_webview::WebViewMainDelegate()); diff --git a/android_webview/native/android_webview_jni_registrar.cc b/android_webview/native/android_webview_jni_registrar.cc new file mode 100644 index 0000000..eb13e11 --- /dev/null +++ b/android_webview/native/android_webview_jni_registrar.cc @@ -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. + +#include "android_webview/native/android_webview_jni_registrar.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" + +namespace android_webview { + +bool RegisterJni(JNIEnv* env) { + return web_contents_delegate_android::RegisterJni(env); +} + +} // namespace android_webview diff --git a/android_webview/native/android_webview_jni_registrar.h b/android_webview/native/android_webview_jni_registrar.h new file mode 100644 index 0000000..a1a3748 --- /dev/null +++ b/android_webview/native/android_webview_jni_registrar.h @@ -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. + +#ifndef ANDROID_WEBVIEW_NATIVE_ANDROID_WEBVIEW_JNI_REGISTRAR_H_ +#define ANDROID_WEBVIEW_NATIVE_ANDROID_WEBVIEW_JNI_REGISTRAR_H_ + +#include <jni.h> + +namespace android_webview { + +// Register all JNI bindings necessary for chrome. +bool RegisterJni(JNIEnv* env); + +} // namespace android_webview + +#endif // ANDROID_WEBVIEW_NATIVE_ANDROID_WEBVIEW_JNI_REGISTRAR_H_ diff --git a/android_webview/native/aw_web_contents_delegate.cc b/android_webview/native/aw_web_contents_delegate.cc new file mode 100644 index 0000000..7302128 --- /dev/null +++ b/android_webview/native/aw_web_contents_delegate.cc @@ -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. + +#include "android_webview/native/aw_web_contents_delegate.h" + +namespace android_webview { + +AwWebContentsDelegate::AwWebContentsDelegate( + JNIEnv* env, + jobject obj) + : WebContentsDelegateAndroid(env, obj) { +} + +AwWebContentsDelegate::~AwWebContentsDelegate() { +} + +} // namespace android_webview diff --git a/android_webview/native/aw_web_contents_delegate.h b/android_webview/native/aw_web_contents_delegate.h new file mode 100644 index 0000000..add2052 --- /dev/null +++ b/android_webview/native/aw_web_contents_delegate.h @@ -0,0 +1,26 @@ +// 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_WEB_CONTENTS_DELEGATE_H_ +#define ANDROID_WEBVIEW_NATIVE_AW_WEB_CONTENTS_DELEGATE_H_ + +#include <jni.h> + +#include "chrome/browser/component/web_contents_delegate_android/web_contents_delegate_android.h" + +namespace android_webview { + +// WebView specific WebContentsDelegate. +// Should contain WebContentsDelegate code required by WebView that should not +// be part of the Chromium Android port. +class AwWebContentsDelegate + : public web_contents_delegate_android::WebContentsDelegateAndroid { + public: + AwWebContentsDelegate(JNIEnv* env, jobject obj); + virtual ~AwWebContentsDelegate(); +}; + +} // namespace android_webview + +#endif // ANDROID_WEBVIEW_NATIVE_AW_WEB_CONTENTS_DELEGATE_H_ diff --git a/android_webview/native/webview_native.gyp b/android_webview/native/webview_native.gyp new file mode 100644 index 0000000..7b31a4a --- /dev/null +++ b/android_webview/native/webview_native.gyp @@ -0,0 +1,40 @@ +# 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. +{ + 'variables': { + 'chromium_code': 1, + }, + 'targets': [ + { + 'target_name': 'webview_native', + 'type': 'static_library', + 'dependencies': [ + '../../base/base.gyp:base_static', + '../../chrome/browser/component/components.gyp:web_contents_delegate_android', + 'android_webview_native_jni', + ], + 'include_dirs': [ + '../..', + '../../skia/config', + '<(SHARED_INTERMEDIATE_DIR)/android_webview', + ], + 'sources': [ + 'android_webview_jni_registrar.cc', + 'android_webview_jni_registrar.h', + 'aw_web_contents_delegate.cc', + 'aw_web_contents_delegate.h', + ], + }, + { + 'target_name': 'android_webview_native_jni', + 'type': 'none', + 'sources': [ + ], + 'variables': { + 'jni_gen_dir': 'android_webview', + }, + 'includes': [ '../../build/jni_generator.gypi' ], + }, + ], +} diff --git a/base/android/jni_generator/jni_generator.py b/base/android/jni_generator/jni_generator.py index 7d13751..527f02a 100755 --- a/base/android/jni_generator/jni_generator.py +++ b/base/android/jni_generator/jni_generator.py @@ -158,15 +158,17 @@ def JavaParamToJni(param): 'Lcom/google/android/apps/chrome/infobar/InfoBarContainer$NativeInfoBar', ('Lcom/google/android/apps/chrome/preferences/ChromeNativePreferences$' 'PasswordListObserver'), + 'Lorg/chromium/android_webview/WebViewWebContentsDelegateAndroid', 'Lorg/chromium/base/SystemMessageHandler', + 'Lorg/chromium/chrome/browser/ChromeWebContentsDelegateAndroid', 'Lorg/chromium/chrome/browser/JSModalDialog', 'Lorg/chromium/chrome/browser/ProcessUtils', 'Lorg/chromium/chrome/browser/SelectFileDialog', + 'Lorg/chromium/chrome/browser/component/web_contents_delegate_android/WebContentsDelegateAndroid', 'Lorg/chromium/content/browser/ContentVideoView', 'Lorg/chromium/content/browser/ContentViewClient', 'Lorg/chromium/content/browser/ContentViewCore', 'Lorg/chromium/content/browser/DeviceOrientation', - 'Lorg/chromium/content/browser/FileChooserParams', 'Lorg/chromium/content/browser/FindNotificationDetails', 'Lorg/chromium/content/browser/InterceptedRequestData', 'Lorg/chromium/content/browser/JavaInputStream', diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeWebContentsDelegateAndroid.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeWebContentsDelegateAndroid.java new file mode 100644 index 0000000..73317b1 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeWebContentsDelegateAndroid.java @@ -0,0 +1,16 @@ +// 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.chrome.browser; + +import org.chromium.chrome.browser.component.web_contents_delegate_android.WebContentsDelegateAndroid; + +/** + * Chromium Android specific WebContentsDelegate. + * This file is the Java version of the native class of the same name. + * It should contain empty WebContentsDelegate methods to be implemented by the embedder. + * These methods belong to the Chromium Android port but not to WebView. + */ +public class ChromeWebContentsDelegateAndroid extends WebContentsDelegateAndroid { +} diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ContentViewUtil.java b/chrome/android/java/src/org/chromium/chrome/browser/ContentViewUtil.java new file mode 100644 index 0000000..b8dc0b0 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/ContentViewUtil.java @@ -0,0 +1,25 @@ +// 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.chrome.browser; + +/** + * This class provides a way to create the native WebContents required for instantiating a + * ContentView. + */ +public abstract class ContentViewUtil { + // Don't instantiate me. + private ContentViewUtil() { + } + + /** + * @return pointer to native WebContents instance, suitable for using with a + * (java) ContentViewCore instance. + */ + public static int createNativeWebContents(boolean incognito) { + return nativeCreateNativeWebContents(incognito); + } + + private static native int nativeCreateNativeWebContents(boolean incognito); +} diff --git a/chrome/android/java/src/org/chromium/chrome/browser/component/web_contents_delegate_android/WebContentsDelegateAndroid.java b/chrome/android/java/src/org/chromium/chrome/browser/component/web_contents_delegate_android/WebContentsDelegateAndroid.java new file mode 100644 index 0000000..8572dab --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/component/web_contents_delegate_android/WebContentsDelegateAndroid.java @@ -0,0 +1,110 @@ +// 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.chrome.browser.component.web_contents_delegate_android; + +import android.graphics.Rect; +import android.graphics.RectF; +import android.view.KeyEvent; + +import org.chromium.base.CalledByNative; +import org.chromium.base.JNINamespace; + +/** + * Java peer of the native class of the same name. + */ +@JNINamespace("web_contents_delegate_android") +public class WebContentsDelegateAndroid { + + // Equivalent of WebCore::WebConsoleMessage::LevelTip. + public static final int LOG_LEVEL_TIP = 0; + // Equivalent of WebCore::WebConsoleMessage::LevelLog. + public static final int LOG_LEVEL_LOG = 1; + // Equivalent of WebCore::WebConsoleMessage::LevelWarning. + public static final int LOG_LEVEL_WARNING = 2; + // Equivalent of WebCore::WebConsoleMessage::LevelError. + public static final int LOG_LEVEL_ERROR = 3; + // The most recent load progress callback received from WebContents, as a percentage. + // Initialize to 100 to indicate that we're not in a loading state. + private int mMostRecentProgress = 100; + + public int getMostRecentProgress() { + return mMostRecentProgress; + } + + @CalledByNative + public void openNewTab(String url, boolean incognito) { + } + + @CalledByNative + public boolean addNewContents(int nativeSourceWebContents, int nativeWebContents, + int disposition, Rect initialPosition, boolean userGesture) { + return false; + } + + @CalledByNative + public void closeContents() { + } + + @CalledByNative + public void onUrlStarredChanged(boolean starred) { + } + + @CalledByNative + public void onLoadStarted() { + } + + @CalledByNative + public void onLoadStopped() { + } + + @CalledByNative + public void onTabHeaderStateChanged() { + } + + @SuppressWarnings("unused") + @CalledByNative + private final void onLoadProgressChanged(double progress) { + mMostRecentProgress = (int) (100.0 * progress); + onLoadProgressChanged(mMostRecentProgress); + } + + public void onLoadProgressChanged(int progress) { + } + + @CalledByNative + public void onUpdateUrl(String url) { + } + + @CalledByNative + public boolean takeFocus(boolean reverse) { + return false; + } + + @CalledByNative + public boolean shouldOverrideUrlLoading(String url) { + return false; + } + + @CalledByNative + public void handleKeyboardEvent(KeyEvent event) { + // TODO(bulach): we probably want to re-inject the KeyEvent back into + // the system. Investigate if this is at all possible. + } + + /** + * Report a JavaScript console message. + * + * @param level message level. One of WebContentsDelegateAndroid.LOG_LEVEL*. + * @param message the error message. + * @param lineNumber the line number int the source file at which the error is reported. + * @param sourceId the name of the source file that caused the error. + * @return true if the client will handle logging the message. + */ + @CalledByNative + public boolean addMessageToConsole(int level, String message, int lineNumber, + String sourceId) { + return false; + } +} diff --git a/chrome/browser/android/chrome_jni_registrar.cc b/chrome/browser/android/chrome_jni_registrar.cc index 4cc6ab2..55edcd8 100644 --- a/chrome/browser/android/chrome_jni_registrar.cc +++ b/chrome/browser/android/chrome_jni_registrar.cc @@ -6,18 +6,22 @@ #include "base/android/jni_android.h" #include "base/android/jni_registrar.h" +#include "chrome/browser/android/content_view_util.h" #include "chrome/browser/android/intent_helper.h" #include "chrome/browser/android/process_utils.h" +#include "chrome/browser/component/web_contents_delegate_android/component_jni_registrar.h" namespace chrome { namespace android { static base::android::RegistrationMethod kChromeRegisteredMethods[] = { + { "ContentViewUtil", RegisterContentViewUtil }, { "IntentHelper", RegisterIntentHelper }, { "ProcessUtils", RegisterProcessUtils }, }; bool RegisterJni(JNIEnv* env) { + web_contents_delegate_android::RegisterJni(env); return RegisterNativeMethods(env, kChromeRegisteredMethods, arraysize(kChromeRegisteredMethods)); } diff --git a/chrome/browser/android/chrome_web_contents_delegate_android.cc b/chrome/browser/android/chrome_web_contents_delegate_android.cc new file mode 100644 index 0000000..56163c4 --- /dev/null +++ b/chrome/browser/android/chrome_web_contents_delegate_android.cc @@ -0,0 +1,36 @@ +// 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 "chrome/browser/android/chrome_web_contents_delegate_android.h" + +#include "base/android/jni_android.h" +#include "chrome/browser/file_select_helper.h" +#include "content/public/browser/web_contents.h" +#include "content/public/common/file_chooser_params.h" + +using base::android::AttachCurrentThread; +using base::android::GetClass; +using base::android::ScopedJavaLocalRef; +using content::FileChooserParams; +using content::WebContents; + +namespace chrome { +namespace android { + +ChromeWebContentsDelegateAndroid::ChromeWebContentsDelegateAndroid(JNIEnv* env, + jobject obj) + : WebContentsDelegateAndroid(env, obj) { +} + +ChromeWebContentsDelegateAndroid::~ChromeWebContentsDelegateAndroid() { +} + +void ChromeWebContentsDelegateAndroid::RunFileChooser( + WebContents* web_contents, + const FileChooserParams& params) { + FileSelectHelper::RunFileChooser(web_contents, params); +} + +} // namespace android +} // namespace chrome diff --git a/chrome/browser/android/chrome_web_contents_delegate_android.h b/chrome/browser/android/chrome_web_contents_delegate_android.h new file mode 100644 index 0000000..beba28f --- /dev/null +++ b/chrome/browser/android/chrome_web_contents_delegate_android.h @@ -0,0 +1,37 @@ +// 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 CHROME_BROWSER_ANDROID_CHROME_WEB_CONTENTS_DELEGATE_ANDROID_H_ +#define CHROME_BROWSER_ANDROID_CHROME_WEB_CONTENTS_DELEGATE_ANDROID_H_ + +#include <jni.h> + +#include "chrome/browser/component/web_contents_delegate_android/web_contents_delegate_android.h" + +namespace content { +struct FileChooserParams; +class WebContents; +} + +namespace chrome { +namespace android { + +// Chromium Android specific WebContentsDelegate. +// Should contain any WebContentsDelegate implementations required by +// the Chromium Android port but not to be shared with WebView. +class ChromeWebContentsDelegateAndroid + : public web_contents_delegate_android::WebContentsDelegateAndroid { + public: + ChromeWebContentsDelegateAndroid(JNIEnv* env, jobject obj); + virtual ~ChromeWebContentsDelegateAndroid(); + + virtual void RunFileChooser(content::WebContents* web_contents, + const content::FileChooserParams& params) + OVERRIDE; +}; + +} // namespace android +} // namespace chrome + +#endif // CHROME_BROWSER_ANDROID_CHROME_WEB_CONTENTS_DELEGATE_ANDROID_H_ diff --git a/chrome/browser/android/content_view_util.cc b/chrome/browser/android/content_view_util.cc new file mode 100644 index 0000000..abcab24 --- /dev/null +++ b/chrome/browser/android/content_view_util.cc @@ -0,0 +1,29 @@ +// 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 "chrome/browser/android/content_view_util.h" + +#include "base/android/jni_android.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/profiles/profile_manager.h" +#include "content/public/browser/web_contents.h" +#include "ipc/ipc_message.h" +#include "jni/ContentViewUtil_jni.h" + +static jint CreateNativeWebContents( + JNIEnv* env, jclass clazz, jboolean incognito) { + Profile* profile = g_browser_process->profile_manager()->GetDefaultProfile(); + if (incognito) + profile = profile->GetOffTheRecordProfile(); + + content::WebContents* web_contents = + content::WebContents::Create(profile, 0, MSG_ROUTING_NONE, 0); + return reinterpret_cast<jint>(web_contents); +} + +bool RegisterContentViewUtil(JNIEnv* env) { + return RegisterNativesImpl(env); +} + diff --git a/chrome/browser/android/content_view_util.h b/chrome/browser/android/content_view_util.h new file mode 100644 index 0000000..ea68300 --- /dev/null +++ b/chrome/browser/android/content_view_util.h @@ -0,0 +1,14 @@ +// 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 CHROME_BROWSER_ANDROID_CONTENT_VIEW_UTIL_H_ +#define CHROME_BROWSER_ANDROID_CONTENT_VIEW_UTIL_H_ + +#include "base/android/jni_android.h" + +// Register the ContentViewUtil's native methods through JNI. +bool RegisterContentViewUtil(JNIEnv* env); + +#endif // CHROME_BROWSER_ANDROID_CONTENT_VIEW_UTIL_H_ + diff --git a/chrome/browser/component/DEPS b/chrome/browser/component/DEPS new file mode 100644 index 0000000..688b78c --- /dev/null +++ b/chrome/browser/component/DEPS @@ -0,0 +1,4 @@ +include_rules = [ + "-chrome/browser", + "+chrome/browser/api", +] diff --git a/chrome/browser/component/OWNERS b/chrome/browser/component/OWNERS new file mode 100644 index 0000000..4975363 --- /dev/null +++ b/chrome/browser/component/OWNERS @@ -0,0 +1 @@ +joi@chromium.org diff --git a/chrome/browser/component/components.gyp b/chrome/browser/component/components.gyp new file mode 100644 index 0000000..3088d96 --- /dev/null +++ b/chrome/browser/component/components.gyp @@ -0,0 +1,29 @@ +# 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. + +{ + 'includes': [ + 'web_contents_delegate_android/web_contents_delegate_android.gypi' + ], + + 'conditions': [ + ['OS=="android"', { + 'targets': [ + { + 'target_name': 'browser_component_jni_headers', + 'type': 'none', + 'sources': [ + '../../android/java/src/org/chromium/chrome/browser/component/web_contents_delegate_android/WebContentsDelegateAndroid.java', + ], + 'variables': { + 'jni_gen_dir': 'chrome/browser_component', + }, + 'includes': [ '../../../build/jni_generator.gypi' ], + }, + ], + }], + ], +} + diff --git a/chrome/browser/component/web_contents_delegate_android/DEPS b/chrome/browser/component/web_contents_delegate_android/DEPS new file mode 100644 index 0000000..beaf5c3 --- /dev/null +++ b/chrome/browser/component/web_contents_delegate_android/DEPS @@ -0,0 +1,3 @@ +include_rules = [ + "+chrome/browser/component/web_contents_delegate_android", +] diff --git a/chrome/browser/component/web_contents_delegate_android/component_jni_registrar.cc b/chrome/browser/component/web_contents_delegate_android/component_jni_registrar.cc new file mode 100644 index 0000000..8c6ae59 --- /dev/null +++ b/chrome/browser/component/web_contents_delegate_android/component_jni_registrar.cc @@ -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. + +#include "chrome/browser/component/web_contents_delegate_android/component_jni_registrar.h" + +#include "base/android/jni_android.h" +#include "base/android/jni_registrar.h" +#include "chrome/browser/component/web_contents_delegate_android/web_contents_delegate_android.h" + +namespace web_contents_delegate_android { + +static base::android::RegistrationMethod kComponentRegisteredMethods[] = { + { "WebContentsDelegateAndroid", RegisterWebContentsDelegateAndroid }, +}; + +bool RegisterJni(JNIEnv* env) { + return RegisterNativeMethods(env, + kComponentRegisteredMethods, arraysize(kComponentRegisteredMethods)); +} + +} // namespace web_contents_delegate_android + diff --git a/chrome/browser/component/web_contents_delegate_android/component_jni_registrar.h b/chrome/browser/component/web_contents_delegate_android/component_jni_registrar.h new file mode 100644 index 0000000..6132bfc --- /dev/null +++ b/chrome/browser/component/web_contents_delegate_android/component_jni_registrar.h @@ -0,0 +1,19 @@ +// 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 CHROME_BROWSER_COMPONENT_WEB_CONTENTS_DELEGATE_ANDROID_COMPONENT_JNI_REGISTRAR_H_ +#define CHROME_BROWSER_COMPONENT_WEB_CONTENTS_DELEGATE_ANDROID_COMPONENT_JNI_REGISTRAR_H_ + +#include <jni.h> + +namespace web_contents_delegate_android { + +// Register all JNI bindings necessary for the web_contents_delegate_android +// component. +bool RegisterJni(JNIEnv* env); + +} // namespace web_contents_delegate_android + +#endif // CHROME_BROWSER_COMPONENT_WEB_CONTENTS_DELEGATE_ANDROID_COMPONENT_JNI_REGISTRAR_H_ + 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 new file mode 100644 index 0000000..6659e2b --- /dev/null +++ b/chrome/browser/component/web_contents_delegate_android/web_contents_delegate_android.cc @@ -0,0 +1,357 @@ +// 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 "chrome/browser/component/web_contents_delegate_android/web_contents_delegate_android.h" + +#include <android/keycodes.h> + +#include "base/android/jni_android.h" +#include "base/android/jni_string.h" +#include "content/public/browser/render_widget_host_view.h" +#include "content/public/browser/download_item.h" +#include "content/public/browser/invalidate_type.h" +#include "content/public/browser/page_navigator.h" +#include "content/public/browser/navigation_controller.h" +#include "content/public/browser/navigation_entry.h" +#include "content/public/browser/web_contents.h" +#include "content/public/common/page_transition_types.h" +#include "content/public/common/referrer.h" +#include "jni/WebContentsDelegateAndroid_jni.h" +#include "net/http/http_request_headers.h" +#include "ui/gfx/rect.h" +#include "webkit/glue/window_open_disposition.h" + +using base::android::AttachCurrentThread; +using base::android::CheckException; +using base::android::ConvertUTF8ToJavaString; +using base::android::ConvertUTF16ToJavaString; +using base::android::GetClass; +using base::android::GetMethodID; +using base::android::HasClass; +using base::android::ScopedJavaLocalRef; +using content::DownloadItem; +using content::JavaScriptDialogCreator; +using content::RenderViewHost; +using content::WebContents; + +namespace web_contents_delegate_android { + +WebContentsDelegateAndroid::WebContentsDelegateAndroid(JNIEnv* env, jobject obj) + : weak_java_delegate_(env, obj), + javascript_dialog_creator_(NULL) { +} + +WebContentsDelegateAndroid::~WebContentsDelegateAndroid() { +} + +ScopedJavaLocalRef<jobject> +WebContentsDelegateAndroid::GetJavaDelegate(JNIEnv* env) const { + return weak_java_delegate_.get(env); +} + +// ---------------------------------------------------------------------------- +// WebContentsDelegate methods +// ---------------------------------------------------------------------------- + +// OpenURLFromTab() will be called when we're performing a browser-intiated +// navigation. The most common scenario for this is opening new tabs (see +// RenderViewImpl::decidePolicyForNavigation for more details). +WebContents* WebContentsDelegateAndroid::OpenURLFromTab( + WebContents* source, + const content::OpenURLParams& params) { + const GURL& url = params.url; + WindowOpenDisposition disposition = params.disposition; + content::PageTransition transition( + PageTransitionFromInt(params.transition)); + + if (!source || (disposition != CURRENT_TAB && + disposition != NEW_FOREGROUND_TAB && + disposition != NEW_BACKGROUND_TAB && + disposition != OFF_THE_RECORD)) { + NOTIMPLEMENTED(); + return NULL; + } + + JNIEnv* env = AttachCurrentThread(); + ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env); + if (obj.is_null()) + return WebContentsDelegate::OpenURLFromTab(source, params); + + if (disposition == NEW_FOREGROUND_TAB || + disposition == NEW_BACKGROUND_TAB || + disposition == OFF_THE_RECORD) { + JNIEnv* env = AttachCurrentThread(); + ScopedJavaLocalRef<jstring> java_url = + ConvertUTF8ToJavaString(env, url.spec()); + Java_WebContentsDelegateAndroid_openNewTab(env, + obj.obj(), + java_url.obj(), + disposition == OFF_THE_RECORD); + return NULL; + } + + // TODO(mkosiba): This should be in platform_utils OpenExternal, b/6174564. + if (transition == content::PAGE_TRANSITION_LINK && ShouldOverrideLoading(url)) + return NULL; + + source->GetController().LoadURL(url, params.referrer, transition, + std::string()); + return source; +} + +// ShouldIgnoreNavigation will be called for every non-local top level +// navigation made by the renderer. If true is returned the renderer will +// not perform the navigation. This is done by using synchronous IPC so we +// should avoid blocking calls from this method. +bool WebContentsDelegateAndroid::ShouldIgnoreNavigation( + WebContents* source, + const GURL& url, + const content::Referrer& referrer, + WindowOpenDisposition disposition, + content::PageTransition transition_type) { + + // Don't override new tabs. + if (disposition == NEW_FOREGROUND_TAB || + disposition == NEW_BACKGROUND_TAB || + disposition == OFF_THE_RECORD) + return false; + + return ShouldOverrideLoading(url); +} + +void WebContentsDelegateAndroid::NavigationStateChanged( + const WebContents* source, unsigned changed_flags) { + if (changed_flags & ( + content::INVALIDATE_TYPE_TAB | content::INVALIDATE_TYPE_TITLE)) { + JNIEnv* env = AttachCurrentThread(); + ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env); + if (obj.is_null()) + return; + Java_WebContentsDelegateAndroid_onTabHeaderStateChanged( + env, obj.obj()); + } +} + +void WebContentsDelegateAndroid::AddNewContents( + WebContents* source, + WebContents* new_contents, + WindowOpenDisposition disposition, + const gfx::Rect& initial_pos, + bool user_gesture) { + JNIEnv* env = AttachCurrentThread(); + ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env); + bool handled = false; + if (!obj.is_null()) { + handled = Java_WebContentsDelegateAndroid_addNewContents( + env, + obj.obj(), + reinterpret_cast<jint>(source), + reinterpret_cast<jint>(new_contents), + static_cast<jint>(disposition), + NULL, + user_gesture); + } + if (!handled) + delete new_contents; +} + +void WebContentsDelegateAndroid::ActivateContents(WebContents* contents) { + // TODO(dtrainor) When doing the merge I came across this. Should we be + // activating this tab here? +} + +void WebContentsDelegateAndroid::DeactivateContents(WebContents* contents) { + // Do nothing. +} + +void WebContentsDelegateAndroid::LoadingStateChanged(WebContents* source) { + JNIEnv* env = AttachCurrentThread(); + ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env); + if (obj.is_null()) + return; + bool has_stopped = source == NULL || !source->IsLoading(); + + if (has_stopped) + Java_WebContentsDelegateAndroid_onLoadStopped(env, obj.obj()); + else + Java_WebContentsDelegateAndroid_onLoadStarted(env, obj.obj()); +} + +void WebContentsDelegateAndroid::LoadProgressChanged(WebContents* source, + double progress) { + JNIEnv* env = AttachCurrentThread(); + ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env); + if (obj.is_null()) + return; + Java_WebContentsDelegateAndroid_onLoadProgressChanged( + env, + obj.obj(), + progress); +} + +void WebContentsDelegateAndroid::CloseContents(WebContents* source) { + JNIEnv* env = AttachCurrentThread(); + ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env); + if (obj.is_null()) + return; + Java_WebContentsDelegateAndroid_closeContents(env, obj.obj()); +} + +void WebContentsDelegateAndroid::MoveContents(WebContents* source, + const gfx::Rect& pos) { + // Do nothing. +} + +bool WebContentsDelegateAndroid::AddMessageToConsole( + WebContents* source, + int32 level, + const string16& message, + int32 line_no, + const string16& source_id) { + JNIEnv* env = AttachCurrentThread(); + ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env); + if (obj.is_null()) + return WebContentsDelegate::AddMessageToConsole(source, level, message, + line_no, source_id); + ScopedJavaLocalRef<jstring> jmessage(ConvertUTF16ToJavaString(env, message)); + ScopedJavaLocalRef<jstring> jsource_id( + ConvertUTF16ToJavaString(env, source_id)); + int jlevel = WEB_CONTENTS_DELEGATE_LOG_LEVEL_TIP; + switch (level) { + case logging::LOG_VERBOSE: + jlevel = WEB_CONTENTS_DELEGATE_LOG_LEVEL_TIP; + break; + case logging::LOG_INFO: + jlevel = WEB_CONTENTS_DELEGATE_LOG_LEVEL_LOG; + break; + case logging::LOG_WARNING: + jlevel = WEB_CONTENTS_DELEGATE_LOG_LEVEL_WARNING; + break; + case logging::LOG_ERROR: + jlevel = WEB_CONTENTS_DELEGATE_LOG_LEVEL_ERROR; + break; + default: + NOTREACHED(); + } + return Java_WebContentsDelegateAndroid_addMessageToConsole( + env, + GetJavaDelegate(env).obj(), + jlevel, + jmessage.obj(), + line_no, + jsource_id.obj()); +} + +// TODO(merge): WARNING! method no longer available on the base class. +// See http://b/issue?id=5862108 +void WebContentsDelegateAndroid::URLStarredChanged(WebContents* source, + bool starred) { + JNIEnv* env = AttachCurrentThread(); + ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env); + if (obj.is_null()) + return; + Java_WebContentsDelegateAndroid_onUrlStarredChanged(env, obj.obj(), starred); +} + +// This is either called from TabContents::DidNavigateMainFramePostCommit() with +// an empty GURL or responding to RenderViewHost::OnMsgUpateTargetURL(). In +// Chrome, the latter is not always called, especially not during history +// navigation. So we only handle the first case and pass the source TabContents' +// url to Java to update the UI. +void WebContentsDelegateAndroid::UpdateTargetURL(WebContents* source, + int32 page_id, + const GURL& url) { + if (!url.is_empty()) + return; + JNIEnv* env = AttachCurrentThread(); + ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env); + if (obj.is_null()) + return; + ScopedJavaLocalRef<jstring> java_url = + ConvertUTF8ToJavaString(env, source->GetURL().spec()); + Java_WebContentsDelegateAndroid_onUpdateUrl(env, + obj.obj(), + java_url.obj()); +} + +bool WebContentsDelegateAndroid::CanDownload( + RenderViewHost* source, + int request_id, + const std::string& request_method) { + if (request_method == net::HttpRequestHeaders::kGetMethod) { + // TODO(leandrogracia): re-enable this when calling DownloadController + // doesn't introduce a DEPS layering violation. + // DownloadController::GetInstance()->CreateGETDownload( + // source, request_id); + return false; + } + return true; +} + +void WebContentsDelegateAndroid::OnStartDownload(WebContents* source, + DownloadItem* download) { + // TODO(leandrogracia): re-enable this when calling DownloadController + // doesn't introduce a DEPS layering violation. + // DownloadController::GetInstance()->OnPostDownloadStarted( + // source, download); +} + +bool WebContentsDelegateAndroid::ShouldOverrideLoading(const GURL& url) { + if (!url.is_valid()) + return false; + + JNIEnv* env = AttachCurrentThread(); + ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env); + if (obj.is_null()) + return WebContentsDelegate::ShouldOverrideLoading(url); + ScopedJavaLocalRef<jstring> jstring_url = + ConvertUTF8ToJavaString(env, url.spec()); + bool ret = Java_WebContentsDelegateAndroid_shouldOverrideUrlLoading( + env, obj.obj(), jstring_url.obj()); + return ret; +} + +void WebContentsDelegateAndroid::HandleKeyboardEvent( + content::WebContents* source, + const content::NativeWebKeyboardEvent& event) { + jobject key_event = event.os_event; + if (key_event) { + JNIEnv* env = AttachCurrentThread(); + ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env); + if (obj.is_null()) + return; + Java_WebContentsDelegateAndroid_handleKeyboardEvent( + env, obj.obj(), key_event); + } +} + +bool WebContentsDelegateAndroid::TakeFocus(WebContents* source, bool reverse) { + JNIEnv* env = AttachCurrentThread(); + ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env); + if (obj.is_null()) + return WebContentsDelegate::TakeFocus(source, reverse); + return Java_WebContentsDelegateAndroid_takeFocus( + env, obj.obj(), reverse); +} + +JavaScriptDialogCreator* + WebContentsDelegateAndroid::GetJavaScriptDialogCreator() { + return javascript_dialog_creator_; +} + +// ---------------------------------------------------------------------------- +// Native JNI methods +// ---------------------------------------------------------------------------- + +// Register native methods + +bool RegisterWebContentsDelegateAndroid(JNIEnv* env) { + if (!HasClass(env, kWebContentsDelegateAndroidClassPath)) { + DLOG(ERROR) << "Unable to find class WebContentsDelegateAndroid!"; + return false; + } + return RegisterNativesImpl(env); +} + +} // namespace web_contents_delegate_android 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 new file mode 100644 index 0000000..5d3aeb8 --- /dev/null +++ b/chrome/browser/component/web_contents_delegate_android/web_contents_delegate_android.gypi @@ -0,0 +1,34 @@ +# 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. + +{ + 'targets': [ + { + 'target_name': 'web_contents_delegate_android', + 'type': 'static_library', + 'dependencies': [ + '../../../base/base.gyp:base', + '../../../content/content.gyp:content_browser', + '../../../content/content.gyp:content_common', + '../../../net/net.gyp:net', + '../../../skia/skia.gyp:skia', + '../../../ui/ui.gyp:ui', + '../../../webkit/support/webkit_support.gyp:glue', + 'browser_component_jni_headers', + ], + 'include_dirs': [ + '../../..', + '../../../skia/config', + '<(SHARED_INTERMEDIATE_DIR)/chrome/browser_component', + ], + 'sources': [ + 'component_jni_registrar.cc', + 'component_jni_registrar.h', + 'web_contents_delegate_android.cc', + 'web_contents_delegate_android.h', + ], + }, + ], +} 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 new file mode 100644 index 0000000..a542707 --- /dev/null +++ b/chrome/browser/component/web_contents_delegate_android/web_contents_delegate_android.h @@ -0,0 +1,128 @@ +// 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 CHROME_BROWSER_COMPONENT_WEB_CONTENTS_DELEGATE_ANDROID_WEB_CONTENTS_DELEGATE_ANDROID_H_ +#define CHROME_BROWSER_COMPONENT_WEB_CONTENTS_DELEGATE_ANDROID_WEB_CONTENTS_DELEGATE_ANDROID_H_ + +#include "base/android/jni_helper.h" +#include "base/android/scoped_java_ref.h" +#include "base/compiler_specific.h" +#include "base/memory/scoped_ptr.h" +#include "content/public/browser/native_web_keyboard_event.h" +#include "content/public/browser/web_contents_delegate.h" +#include "content/public/browser/web_contents_observer.h" +#include "content/public/common/javascript_message_type.h" +#include "content/public/common/referrer.h" +#include "googleurl/src/gurl.h" +#include "net/base/net_errors.h" + +namespace content { +class DownloadItem; +class JavaScriptDialogCreator; +class RenderViewHost; +class WebContents; +class WebContentsObserver; +struct NativeWebKeyboardEvent; +} + +namespace web_contents_delegate_android { + +enum WebContentsDelegateLogLevel { + // Equivalent of WebCore::WebConsoleMessage::LevelTip. + WEB_CONTENTS_DELEGATE_LOG_LEVEL_TIP = 0, + // Equivalent of WebCore::WebConsoleMessage::LevelLog. + WEB_CONTENTS_DELEGATE_LOG_LEVEL_LOG = 1, + // Equivalent of WebCore::WebConsoleMessage::LevelWarning. + WEB_CONTENTS_DELEGATE_LOG_LEVEL_WARNING = 2, + // Equivalent of WebCore::WebConsoleMessage::LevelError. + WEB_CONTENTS_DELEGATE_LOG_LEVEL_ERROR = 3, +}; + + +// Native underpinnings of WebContentsDelegateAndroid.java. Provides a default +// delegate for WebContents to forward calls to the java peer. The embedding +// application may subclass and override methods on either the C++ or Java side +// as required. +class WebContentsDelegateAndroid : public content::WebContentsDelegate { + public: + WebContentsDelegateAndroid(JNIEnv* env, jobject obj); + virtual ~WebContentsDelegateAndroid(); + + // Binds this WebContentsDelegateAndroid to the passed WebContents instance, + // such that when that WebContents is destroyed, this + // WebContentsDelegateAndroid instance will be destroyed too. + void SetOwnerWebContents(content::WebContents* contents); + + // Overridden from WebContentsDelegate: + virtual content::WebContents* OpenURLFromTab( + content::WebContents* source, + const content::OpenURLParams& params) OVERRIDE; + virtual bool ShouldIgnoreNavigation( + content::WebContents* source, + const GURL& url, + const content::Referrer& referrer, + WindowOpenDisposition disposition, + content::PageTransition transition_type) OVERRIDE; + virtual void NavigationStateChanged(const content::WebContents* source, + unsigned changed_flags) OVERRIDE; + virtual void AddNewContents(content::WebContents* source, + content::WebContents* new_contents, + WindowOpenDisposition disposition, + const gfx::Rect& initial_pos, + bool user_gesture) OVERRIDE; + virtual void ActivateContents(content::WebContents* contents) OVERRIDE; + virtual void DeactivateContents(content::WebContents* contents) OVERRIDE; + virtual void LoadingStateChanged(content::WebContents* source) OVERRIDE; + virtual void LoadProgressChanged(content::WebContents* source, + double load_progress) OVERRIDE; + virtual void CloseContents(content::WebContents* source) OVERRIDE; + virtual void MoveContents(content::WebContents* source, + const gfx::Rect& pos) OVERRIDE; + virtual bool AddMessageToConsole(content::WebContents* source, + int32 level, + const string16& message, + int32 line_no, + const string16& source_id) OVERRIDE; + // TODO(merge): WARNING! method no longer available on the base class. + // See http://b/issue?id=5862108 + virtual void URLStarredChanged(content::WebContents* source, bool starred); + virtual void UpdateTargetURL(content::WebContents* source, + int32 page_id, + const GURL& url) OVERRIDE; + virtual bool CanDownload(content::RenderViewHost* source, + int request_id, + const std::string& request_method) OVERRIDE; + virtual void OnStartDownload(content::WebContents* source, + content::DownloadItem* download) OVERRIDE; + virtual bool ShouldOverrideLoading(const GURL& url) OVERRIDE; + virtual void HandleKeyboardEvent( + content::WebContents* source, + const content::NativeWebKeyboardEvent& event) OVERRIDE; + virtual content::JavaScriptDialogCreator* GetJavaScriptDialogCreator() + OVERRIDE; + virtual bool TakeFocus(content::WebContents* source, bool reverse) OVERRIDE; + + void SetJavaScriptDialogCreator( + content::JavaScriptDialogCreator* javascript_dialog_creator) { + javascript_dialog_creator_ = javascript_dialog_creator; + } + + protected: + base::android::ScopedJavaLocalRef<jobject> GetJavaDelegate(JNIEnv* env) const; + + private: + // We depend on the java side user of WebContentDelegateAndroid to hold a + // strong reference to that object as long as they want to receive callbacks + // on it. Using a weak ref here allows it to be correctly GCed. + JavaObjectWeakGlobalRef weak_java_delegate_; + + // The object responsible for creating JavaScript dialogs. + content::JavaScriptDialogCreator* javascript_dialog_creator_; +}; + +bool RegisterWebContentsDelegateAndroid(JNIEnv* env); + +} // namespace web_contents_delegate_android + +#endif // CHROME_BROWSER_COMPONENT_WEB_CONTENTS_DELEGATE_ANDROID_WEB_CONTENTS_DELEGATE_ANDROID_H_ diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 99dff13..51d26a6 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -116,6 +116,10 @@ 'browser/android/chrome_jni_registrar.h', 'browser/android/chrome_startup_flags.cc', 'browser/android/chrome_startup_flags.h', + 'browser/android/chrome_web_contents_delegate_android.cc', + 'browser/android/chrome_web_contents_delegate_android.h', + 'browser/android/content_view_util.cc', + 'browser/android/content_view_util.h', 'browser/android/devtools_server.cc', 'browser/android/devtools_server.h', 'browser/android/intent_helper.cc', @@ -4980,6 +4984,7 @@ }], ['OS=="android"', { 'dependencies': [ + 'browser/component/components.gyp:web_contents_delegate_android', 'chrome_browser_jni_headers', ], 'sources': [ @@ -5605,6 +5610,7 @@ 'sources': [ 'android/java/src/org/chromium/chrome/browser/AndroidProtocolAdapter.java', 'android/java/src/org/chromium/chrome/browser/ChromeHttpAuthHandler.java', + 'android/java/src/org/chromium/chrome/browser/ContentViewUtil.java', 'android/java/src/org/chromium/chrome/browser/IntentHelper.java', 'android/java/src/org/chromium/chrome/browser/ProcessUtils.java', ], diff --git a/content/browser/android/content_util.cc b/content/browser/android/content_util.cc deleted file mode 100644 index 0169cfc..0000000 --- a/content/browser/android/content_util.cc +++ /dev/null @@ -1,81 +0,0 @@ -// 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 "content/browser/android/content_util.h" - -#include "base/android/jni_android.h" -#include "base/android/jni_array.h" -#include "base/android/jni_string.h" -#include "content/browser/web_contents/web_contents_impl.h" - -using base::android::AppendJavaStringArrayToStringVector; -using base::android::CheckException; -using base::android::ConvertJavaStringToUTF8; -using base::android::ConvertJavaStringToUTF16; -using base::android::ConvertUTF8ToJavaString; -using base::android::ConvertUTF16ToJavaString; -using base::android::GetClass; -using base::android::GetFieldID; -using base::android::GetMethodID; -using base::android::JavaRef; -using base::android::ScopedJavaLocalRef; -using base::android::ToJavaArrayOfStrings; - -namespace { - -const char kFileChooserParamsClassName[] = - "org/chromium/content/browser/FileChooserParams"; - -} - -namespace content { - -ScopedJavaLocalRef<jobject> ToJavaFileChooserParams( - JNIEnv* env, const FileChooserParams& file_chooser_params) { - ScopedJavaLocalRef<jclass> clazz = GetClass(env, kFileChooserParamsClassName); - jmethodID constructor_id = GetMethodID(env, clazz, "<init>", - "(ILjava/lang/String;Ljava/lang/String;[Ljava/lang/String;" - "Ljava/lang/String;)V"); - - ScopedJavaLocalRef<jstring> title = - ConvertUTF16ToJavaString(env, file_chooser_params.title); - ScopedJavaLocalRef<jstring> default_file_name = - ConvertUTF8ToJavaString(env, - file_chooser_params.default_file_name.value()); - ScopedJavaLocalRef<jobjectArray> accept_types = - ToJavaArrayOfStrings(env, file_chooser_params.accept_types); - ScopedJavaLocalRef<jstring> capture = - ConvertUTF16ToJavaString(env, file_chooser_params.capture); - - ScopedJavaLocalRef<jobject> java_params(env, - env->NewObject(clazz.obj(), - constructor_id, - static_cast<jint>(file_chooser_params.mode), - title.obj(), - default_file_name.obj(), - accept_types.obj(), - capture.obj())); - CheckException(env); - - return java_params; -} - -FileChooserParams ToNativeFileChooserParams( - JNIEnv* env, jint mode, jstring title, jstring default_file, - jobjectArray accept_types, jstring capture) { - FileChooserParams file_chooser_params; - file_chooser_params.mode = - static_cast<FileChooserParams::Mode>(mode); - file_chooser_params.title = ConvertJavaStringToUTF16(env, title); - file_chooser_params.default_file_name = - FilePath(ConvertJavaStringToUTF8(env, default_file)); - AppendJavaStringArrayToStringVector(env, accept_types, - &file_chooser_params.accept_types); - file_chooser_params.capture = ConvertJavaStringToUTF16(env, capture); - - return file_chooser_params; -} - -} // namespace content - diff --git a/content/browser/android/content_util.h b/content/browser/android/content_util.h deleted file mode 100644 index aa35c45..0000000 --- a/content/browser/android/content_util.h +++ /dev/null @@ -1,30 +0,0 @@ -// 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 CONTENT_BROWSER_ANDROID_CONTENT_UTIL_H_ -#define CONTENT_BROWSER_ANDROID_CONTENT_UTIL_H_ - -#include <jni.h> - -#include "base/android/jni_android.h" -#include "base/android/scoped_java_ref.h" -#include "content/public/common/file_chooser_params.h" - -namespace content { - -base::android::ScopedJavaLocalRef<jobject> ToJavaFileChooserParams( - JNIEnv* env, - const FileChooserParams& file_chooser_params); - -content::FileChooserParams ToNativeFileChooserParams( - JNIEnv* env, - jint mode, - jstring title, - jstring default_file, - jobjectArray accept_types, - jstring capture); - -}; // namespace content - -#endif // CONTENT_BROWSER_ANDROID_CONTENT_UTIL_H_ diff --git a/content/browser/android/content_view_client.cc b/content/browser/android/content_view_client.cc index d4e08fb..b7d4a15 100644 --- a/content/browser/android/content_view_client.cc +++ b/content/browser/android/content_view_client.cc @@ -8,12 +8,9 @@ #include "base/android/jni_android.h" #include "base/android/jni_string.h" -#include "content/browser/android/content_util.h" #include "content/browser/android/content_view_core_impl.h" #include "content/browser/android/download_controller.h" -#include "content/browser/android/ime_utils.h" #include "content/browser/renderer_host/render_view_host_impl.h" -#include "content/common/find_match_rect_android.h" #include "content/public/browser/render_widget_host_view.h" #include "content/public/browser/download_item.h" #include "content/public/browser/invalidate_type.h" @@ -25,8 +22,6 @@ #include "content/public/common/referrer.h" #include "jni/ContentViewClient_jni.h" #include "net/http/http_request_headers.h" -#include "ui/gfx/rect.h" -#include "webkit/glue/window_open_disposition.h" using base::android::AttachCurrentThread; using base::android::CheckException; @@ -40,10 +35,7 @@ using base::android::ScopedJavaLocalRef; namespace content { ContentViewClient::ContentViewClient(JNIEnv* env, jobject obj) - : weak_java_client_(env, obj), - find_helper_(NULL), - javascript_dialog_creator_(NULL), - load_progress_(0) { + : weak_java_client_(env, obj) { } ContentViewClient::~ContentViewClient() { @@ -58,42 +50,45 @@ ContentViewClient* ContentViewClient::CreateNativeContentViewClient( void ContentViewClient::OnInternalPageLoadRequest( WebContents* source, const GURL& url) { - last_requested_navigation_url_ = url; } void ContentViewClient::OnPageStarted(const GURL& url) { JNIEnv* env = AttachCurrentThread(); + ScopedJavaLocalRef<jobject> obj = weak_java_client_.get(env); + if (obj.is_null()) + return; ScopedJavaLocalRef<jstring> jstring_url = ConvertUTF8ToJavaString(env, url.spec()); - Java_ContentViewClient_onPageStarted(env, weak_java_client_.get(env).obj(), - jstring_url.obj()); + Java_ContentViewClient_onPageStarted(env, obj.obj(), jstring_url.obj()); } void ContentViewClient::OnPageFinished(const GURL& url) { - if (url == last_requested_navigation_url_) - last_requested_navigation_url_ = GURL::EmptyGURL(); - JNIEnv* env = AttachCurrentThread(); + ScopedJavaLocalRef<jobject> obj = weak_java_client_.get(env); + if (obj.is_null()) + return; ScopedJavaLocalRef<jstring> jstring_url = ConvertUTF8ToJavaString(env, url.spec()); - Java_ContentViewClient_onPageFinished(env, weak_java_client_.get(env).obj(), - jstring_url.obj()); + Java_ContentViewClient_onPageFinished(env, obj.obj(), jstring_url.obj()); CheckException(env); } void ContentViewClient::OnReceivedError(int error_code, - const string16& description, - const GURL& url) { + const string16& description, + const GURL& url) { JNIEnv* env = AttachCurrentThread(); + ScopedJavaLocalRef<jobject> obj = weak_java_client_.get(env); + if (obj.is_null()) + return; ScopedJavaLocalRef<jstring> jstring_error_description = ConvertUTF8ToJavaString(env, url.spec()); ScopedJavaLocalRef<jstring> jstring_url = ConvertUTF8ToJavaString(env, url.spec()); Java_ContentViewClient_onReceivedError( - env, weak_java_client_.get(env).obj(), + env, obj.obj(), ToContentViewClientError(error_code), jstring_error_description.obj(), jstring_url.obj()); } @@ -101,35 +96,33 @@ void ContentViewClient::OnReceivedError(int error_code, void ContentViewClient::OnDidCommitMainFrame(const GURL& url, const GURL& base_url) { JNIEnv* env = AttachCurrentThread(); + ScopedJavaLocalRef<jobject> obj = weak_java_client_.get(env); + if (obj.is_null()) + return; ScopedJavaLocalRef<jstring> jstring_url = ConvertUTF8ToJavaString(env, url.spec()); ScopedJavaLocalRef<jstring> jstring_base_url = ConvertUTF8ToJavaString(env, base_url.spec()); Java_ContentViewClient_onMainFrameCommitted( - env, weak_java_client_.get(env).obj(), + env, obj.obj(), jstring_url.obj(), jstring_base_url.obj()); } void ContentViewClient::OnInterstitialShown() { JNIEnv* env = AttachCurrentThread(); - Java_ContentViewClient_onInterstitialShown( - env, weak_java_client_.get(env).obj()); + ScopedJavaLocalRef<jobject> obj = weak_java_client_.get(env); + if (obj.is_null()) + return; + Java_ContentViewClient_onInterstitialShown(env, obj.obj()); } void ContentViewClient::OnInterstitialHidden() { JNIEnv* env = AttachCurrentThread(); - Java_ContentViewClient_onInterstitialHidden( - env, weak_java_client_.get(env).obj()); -} - -void ContentViewClient::SetFindHelper(FindHelper* find_helper) { - find_helper_ = find_helper; -} - -void ContentViewClient::SetJavaScriptDialogCreator( - JavaScriptDialogCreator* javascript_dialog_creator) { - javascript_dialog_creator_ = javascript_dialog_creator; + ScopedJavaLocalRef<jobject> obj = weak_java_client_.get(env); + if (obj.is_null()) + return; + Java_ContentViewClient_onInterstitialHidden(env, obj.obj()); } bool ContentViewClient::OnJSModalDialog(JavaScriptMessageType type, @@ -138,36 +131,36 @@ bool ContentViewClient::OnJSModalDialog(JavaScriptMessageType type, const string16& message, const string16& default_value) { JNIEnv* env = AttachCurrentThread(); + ScopedJavaLocalRef<jobject> obj = weak_java_client_.get(env); + if (obj.is_null()) + return false; ScopedJavaLocalRef<jstring> jurl(ConvertUTF8ToJavaString(env, url.spec())); ScopedJavaLocalRef<jstring> jmessage(ConvertUTF16ToJavaString(env, message)); // Special case for beforeunload dialogs, as that isn't encoded in the // |type| of the dialog. if (is_before_unload_dialog) { - return Java_ContentViewClient_onJsBeforeUnload(env, - weak_java_client_.get(env).obj(), + return Java_ContentViewClient_onJsBeforeUnload( + env, obj.obj(), jurl.obj(), jmessage.obj()); } switch (type) { case JAVASCRIPT_MESSAGE_TYPE_ALERT: - return Java_ContentViewClient_onJsAlert(env, - weak_java_client_.get(env).obj(), + return Java_ContentViewClient_onJsAlert(env, obj.obj(), jurl.obj(), jmessage.obj()); case JAVASCRIPT_MESSAGE_TYPE_CONFIRM: - return Java_ContentViewClient_onJsConfirm(env, - weak_java_client_.get(env).obj(), - jurl.obj(), - jmessage.obj()); + return Java_ContentViewClient_onJsConfirm(env, obj.obj(), + jurl.obj(), + jmessage.obj()); case JAVASCRIPT_MESSAGE_TYPE_PROMPT: { ScopedJavaLocalRef<jstring> jdefault_value( ConvertUTF16ToJavaString(env, default_value)); - return Java_ContentViewClient_onJsPrompt(env, - weak_java_client_.get(env).obj(), + return Java_ContentViewClient_onJsPrompt(env, obj.obj(), jurl.obj(), jmessage.obj(), jdefault_value.obj()); @@ -179,278 +172,6 @@ bool ContentViewClient::OnJSModalDialog(JavaScriptMessageType type, } } -// ---------------------------------------------------------------------------- -// WebContentsDelegate methods -// ---------------------------------------------------------------------------- - -// OpenURLFromTab() will be called when we're performing a browser-intiated -// navigation. The most common scenario for this is opening new tabs (see -// RenderViewImpl::decidePolicyForNavigation for more details). -WebContents* ContentViewClient::OpenURLFromTab( - WebContents* source, - const OpenURLParams& params) { - const GURL& url = params.url; - WindowOpenDisposition disposition = params.disposition; - PageTransition transition( - PageTransitionFromInt(params.transition)); - - if (!source || (disposition != CURRENT_TAB && - disposition != NEW_FOREGROUND_TAB && - disposition != NEW_BACKGROUND_TAB && - disposition != OFF_THE_RECORD)) { - NOTIMPLEMENTED(); - return NULL; - } - - if (disposition == NEW_FOREGROUND_TAB || - disposition == NEW_BACKGROUND_TAB || - disposition == OFF_THE_RECORD) { - JNIEnv* env = AttachCurrentThread(); - ScopedJavaLocalRef<jstring> java_url = - ConvertUTF8ToJavaString(env, url.spec()); - Java_ContentViewClient_openNewTab(env, - weak_java_client_.get(env).obj(), - java_url.obj(), - disposition == OFF_THE_RECORD); - return NULL; - } - - // TODO(mkosiba): This should be in platform_utils OpenExternal, b/6174564. - if (transition == PAGE_TRANSITION_LINK && ShouldOverrideLoading(url)) - return NULL; - - source->GetController().LoadURL(url, params.referrer, transition, - std::string()); - return source; -} - -// ShouldIgnoreNavigation will be called for every non-local top level -// navigation made by the renderer. If true is returned the renderer will -// not perform the navigation. This is done by using synchronous IPC so we -// should avoid blocking calls from this method. -bool ContentViewClient::ShouldIgnoreNavigation( - WebContents* source, - const GURL& url, - const Referrer& referrer, - WindowOpenDisposition disposition, - PageTransition transition_type) { - - // Don't override new tabs. - if (disposition == NEW_FOREGROUND_TAB || - disposition == NEW_BACKGROUND_TAB || - disposition == OFF_THE_RECORD) - return false; - - // Don't override the navigation that has just been requested via the - // ContentView.loadUrl method. - if (url == last_requested_navigation_url_) { - last_requested_navigation_url_ = GURL::EmptyGURL(); - return false; - } - - return ShouldOverrideLoading(url); -} - -void ContentViewClient::NavigationStateChanged( - const WebContents* source, unsigned changed_flags) { - if (changed_flags & ( - INVALIDATE_TYPE_TAB | INVALIDATE_TYPE_TITLE)) { - JNIEnv* env = AttachCurrentThread(); - Java_ContentViewClient_onTabHeaderStateChanged( - env, weak_java_client_.get(env).obj()); - } -} - -void ContentViewClient::AddNewContents(WebContents* source, - WebContents* new_contents, - WindowOpenDisposition disposition, - const gfx::Rect& initial_pos, - bool user_gesture) { - JNIEnv* env = AttachCurrentThread(); - bool handled = Java_ContentViewClient_addNewContents( - env, - weak_java_client_.get(env).obj(), - reinterpret_cast<jint>(source), - reinterpret_cast<jint>(new_contents), - static_cast<jint>(disposition), - NULL, - user_gesture); - if (!handled) - delete new_contents; -} - -void ContentViewClient::ActivateContents(WebContents* contents) { - // TODO(dtrainor) When doing the merge I came across this. Should we be - // activating this tab here? -} - -void ContentViewClient::DeactivateContents(WebContents* contents) { - // Do nothing. -} - -void ContentViewClient::LoadingStateChanged(WebContents* source) { - JNIEnv* env = AttachCurrentThread(); - bool has_stopped = source == NULL || !source->IsLoading(); - - if (has_stopped) - Java_ContentViewClient_onLoadStopped( - env, weak_java_client_.get(env).obj()); - else - Java_ContentViewClient_onLoadStarted( - env, weak_java_client_.get(env).obj()); -} - -void ContentViewClient::LoadProgressChanged(double progress) { - load_progress_ = progress; - JNIEnv* env = AttachCurrentThread(); - Java_ContentViewClient_onLoadProgressChanged( - env, - weak_java_client_.get(env).obj(), - progress); -} - -double ContentViewClient::GetLoadProgress() const { - return load_progress_; -} - -void ContentViewClient::CloseContents(WebContents* source) { - JNIEnv* env = AttachCurrentThread(); - Java_ContentViewClient_closeContents(env, weak_java_client_.get(env).obj()); -} - -void ContentViewClient::MoveContents(WebContents* source, - const gfx::Rect& pos) { - // Do nothing. -} - -// TODO(merge): WARNING! method no longer available on the base class. -// See http://b/issue?id=5862108 -void ContentViewClient::URLStarredChanged(WebContents* source, bool starred) { - JNIEnv* env = AttachCurrentThread(); - Java_ContentViewClient_onUrlStarredChanged(env, - weak_java_client_.get(env).obj(), - starred); -} - -// This is either called from TabContents::DidNavigateMainFramePostCommit() with -// an empty GURL or responding to RenderViewHost::OnMsgUpateTargetURL(). In -// Chrome, the latter is not always called, especially not during history -// navigation. So we only handle the first case and pass the source TabContents' -// url to Java to update the UI. -void ContentViewClient::UpdateTargetURL(WebContents* source, - int32 page_id, - const GURL& url) { - if (url.is_empty()) { - JNIEnv* env = AttachCurrentThread(); - ScopedJavaLocalRef<jstring> java_url = - ConvertUTF8ToJavaString(env, source->GetURL().spec()); - Java_ContentViewClient_onUpdateUrl(env, - weak_java_client_.get(env).obj(), - java_url.obj()); - } -} - -bool ContentViewClient::CanDownload(RenderViewHost* source, - int request_id, - const std::string& request_method) { - if (request_method == net::HttpRequestHeaders::kGetMethod) { - DownloadController::GetInstance()->CreateGETDownload( - source, request_id); - return false; - } - return true; -} - -void ContentViewClient::OnStartDownload(WebContents* source, - DownloadItem* download) { - DownloadController::GetInstance()->OnPostDownloadStarted( - source, download); -} - -void ContentViewClient::FindReply(WebContents* web_contents, - int request_id, - int number_of_matches, - const gfx::Rect& selection_rect, - int active_match_ordinal, - bool final_update) { - /* TODO(jrg): upstream this; requires - content/browser/android/find_helper.h to be upstreamed */ -} - -void ContentViewClient::OnReceiveFindMatchRects( - int version, const std::vector<FindMatchRect>& rects, - const FindMatchRect& active_rect) { - JNIEnv* env = AttachCurrentThread(); - - // Constructs an float[] of (left, top, right, bottom) tuples and passes it on - // to the Java onReceiveFindMatchRects handler which will use it to create - // RectF objects equivalent to the std::vector<FindMatchRect>. - ScopedJavaLocalRef<jfloatArray> rect_data(env, - env->NewFloatArray(rects.size() * 4)); - jfloat* rect_data_floats = env->GetFloatArrayElements(rect_data.obj(), NULL); - for (size_t i = 0; i < rects.size(); ++i) { - rect_data_floats[4 * i] = rects[i].left; - rect_data_floats[4 * i + 1] = rects[i].top; - rect_data_floats[4 * i + 2] = rects[i].right; - rect_data_floats[4 * i + 3] = rects[i].bottom; - } - env->ReleaseFloatArrayElements(rect_data.obj(), rect_data_floats, 0); - - ScopedJavaLocalRef<jobject> active_rect_object; - if (active_rect.left < active_rect.right && - active_rect.top < active_rect.bottom) { - ScopedJavaLocalRef<jclass> rect_clazz = - GetClass(env, "android/graphics/RectF"); - jmethodID rect_constructor = - GetMethodID(env, rect_clazz, "<init>", "(FFFF)V"); - active_rect_object.Reset(env, env->NewObject(rect_clazz.obj(), - rect_constructor, - active_rect.left, - active_rect.top, - active_rect.right, - active_rect.bottom)); - DCHECK(!active_rect_object.is_null()); - } - - - Java_ContentViewClient_onReceiveFindMatchRects( - env, - weak_java_client_.get(env).obj(), - version, rect_data.obj(), - active_rect_object.obj()); -} - -bool ContentViewClient::ShouldOverrideLoading(const GURL& url) { - if (!url.is_valid()) - return false; - - JNIEnv* env = AttachCurrentThread(); - ScopedJavaLocalRef<jstring> jstring_url = - ConvertUTF8ToJavaString(env, url.spec()); - bool ret = Java_ContentViewClient_shouldOverrideUrlLoading( - env, weak_java_client_.get(env).obj(), jstring_url.obj()); - return ret; -} - -void ContentViewClient::HandleKeyboardEvent( - const NativeWebKeyboardEvent& event) { - jobject key_event = KeyEventFromNative(event); - if (key_event) { - JNIEnv* env = AttachCurrentThread(); - Java_ContentViewClient_handleKeyboardEvent( - env, - weak_java_client_.get(env).obj(), - key_event); - } -} - -bool ContentViewClient::TakeFocus(bool reverse) { - JNIEnv* env = AttachCurrentThread(); - return Java_ContentViewClient_takeFocus(env, - weak_java_client_.get(env).obj(), - reverse); -} - ContentViewClientError ContentViewClient::ToContentViewClientError( int net_error) { // Note: many net::Error constants don't have an obvious mapping. @@ -554,18 +275,6 @@ ContentViewClientError ContentViewClient::ToContentViewClientError( } } -JavaScriptDialogCreator* ContentViewClient::GetJavaScriptDialogCreator() { - return javascript_dialog_creator_; -} - -void ContentViewClient::RunFileChooser( - WebContents* tab, const FileChooserParams& params) { - JNIEnv* env = AttachCurrentThread(); - ScopedJavaLocalRef<jobject> jparams = ToJavaFileChooserParams(env, params); - Java_ContentViewClient_runFileChooser(env, weak_java_client_.get(env).obj(), - jparams.obj()); -} - // ---------------------------------------------------------------------------- // Native JNI methods // ---------------------------------------------------------------------------- diff --git a/content/browser/android/content_view_client.h b/content/browser/android/content_view_client.h index fadec83..815a09f 100644 --- a/content/browser/android/content_view_client.h +++ b/content/browser/android/content_view_client.h @@ -8,7 +8,6 @@ #include "base/android/jni_helper.h" #include "base/compiler_specific.h" #include "content/public/browser/native_web_keyboard_event.h" -#include "content/public/browser/web_contents_delegate.h" #include "content/public/common/javascript_message_type.h" #include "content/public/common/referrer.h" #include "googleurl/src/gurl.h" @@ -17,17 +16,14 @@ class FindHelper; namespace content { + class DownloadItem; -struct FindMatchRect; class JavaScriptDialogCreator; -class NativeWebKeyboardEvent; +struct NativeWebKeyboardEvent; class RenderViewHost; class WebContents; -} - -namespace content { -// This enum must be kept in sync with ContentViewClient.java +// These enums must be kept in sync with ContentViewClient.java enum ContentViewClientError { // Success CONTENT_VIEW_CLIENT_ERROR_OK = 0, @@ -63,11 +59,16 @@ enum ContentViewClientError { CONTENT_VIEW_CLIENT_ERROR_TOO_MANY_REQUESTS = -15, }; -// Native mirror of ContentViewClient.java. Uses as a client of +// Native mirror of ContentViewClient.java. Used as a client of // ContentView, the main FrameLayout on Android. -class ContentViewClient : public WebContentsDelegate { +// TODO(joth): Delete this C++ class, to make it Java-only. All the callbacks +// defined here originate in WebContentsObserver; we should have a dedicated +// bridge class for that rather than overloading ContentViewClient with this. +// See http://crbug.com/137967 +class ContentViewClient { public: ContentViewClient(JNIEnv* env, jobject obj); + ~ContentViewClient(); static ContentViewClient* CreateNativeContentViewClient(JNIEnv* env, jobject obj); @@ -87,7 +88,6 @@ class ContentViewClient : public WebContentsDelegate { void OnInterstitialShown(); void OnInterstitialHidden(); - void SetFindHelper(FindHelper* find_helper); void SetJavaScriptDialogCreator( JavaScriptDialogCreator* javascript_dialog_creator); @@ -97,91 +97,15 @@ class ContentViewClient : public WebContentsDelegate { const string16& message, const string16& default_value); - // Returns the actual load progress, a value between 0 (nothing loaded) and - // 1 (page fully loaded). - virtual double GetLoadProgress() const; - - // Overridden from WebContentsDelegate: - virtual WebContents* OpenURLFromTab( - WebContents* source, - const OpenURLParams& params) OVERRIDE; - virtual bool ShouldIgnoreNavigation( - WebContents* source, - const GURL& url, - const Referrer& referrer, - WindowOpenDisposition disposition, - PageTransition transition_type) OVERRIDE; - virtual void NavigationStateChanged(const WebContents* source, - unsigned changed_flags) OVERRIDE; - virtual void AddNewContents(WebContents* source, - WebContents* new_contents, - WindowOpenDisposition disposition, - const gfx::Rect& initial_pos, - bool user_gesture) OVERRIDE; - virtual void ActivateContents(WebContents* contents) OVERRIDE; - virtual void DeactivateContents(WebContents* contents) OVERRIDE; - virtual void LoadingStateChanged(WebContents* source) OVERRIDE; - virtual void LoadProgressChanged(double load_progress) OVERRIDE; - virtual void CloseContents(WebContents* source) OVERRIDE; - virtual void MoveContents(WebContents* source, - const gfx::Rect& pos) OVERRIDE; - // TODO(merge): WARNING! method no longer available on the base class. - // See http://b/issue?id=5862108 - virtual void URLStarredChanged(WebContents* source, bool starred); - virtual void UpdateTargetURL(WebContents* source, - int32 page_id, - const GURL& url) OVERRIDE; - virtual bool CanDownload(RenderViewHost* source, - int request_id, - const std::string& request_method) OVERRIDE; - virtual void OnStartDownload(WebContents* source, - DownloadItem* download) OVERRIDE; - virtual void FindReply(WebContents* tab, - int request_id, - int number_of_matches, - const gfx::Rect& selection_rect, - int active_match_ordinal, - bool final_update) OVERRIDE; - virtual void OnReceiveFindMatchRects(int version, - const std::vector<FindMatchRect>& rects, - const FindMatchRect& active_rect) OVERRIDE; - virtual bool ShouldOverrideLoading(const GURL& url) OVERRIDE; - virtual void HandleKeyboardEvent( - const NativeWebKeyboardEvent& event) OVERRIDE; - virtual JavaScriptDialogCreator* GetJavaScriptDialogCreator() OVERRIDE; - virtual void RunFileChooser( - WebContents* tab, - const FileChooserParams& params) OVERRIDE; - virtual bool TakeFocus(bool reverse) OVERRIDE; - - virtual ~ContentViewClient(); - private: // Get the closest ContentViewClient match to the given Chrome error code. static ContentViewClientError ToContentViewClientError(int net_error); - // We use this to keep track of whether the navigation we get in - // ShouldIgnoreNavigation has been initiated by the ContentView or not. We - // need the GURL, because the active navigation entry doesn't change on - // redirects. - GURL last_requested_navigation_url_; - // We depend on ContentView.java to hold a ref to the client object. If we // were to hold a hard ref from native we could end up with a cyclic // ownership leak (the GC can't collect cycles if part of the cycle is caused // by native). JavaObjectWeakGlobalRef weak_java_client_; - - // Used to process find replies. Owned by the ContentView. The ContentView - // NULLs this pointer when the FindHelper goes away. - FindHelper* find_helper_; - - // The object responsible for creating JavaScript dialogs. - JavaScriptDialogCreator* javascript_dialog_creator_; - - // Indicates the load state of the page. 0.0 means nothing loaded, 1 means - // fully loaded. - double load_progress_; }; bool RegisterContentViewClient(JNIEnv* env); diff --git a/content/browser/android/content_view_core_impl.cc b/content/browser/android/content_view_core_impl.cc index 23705cf..9b03d89 100644 --- a/content/browser/android/content_view_core_impl.cc +++ b/content/browser/android/content_view_core_impl.cc @@ -237,14 +237,6 @@ ScopedJavaLocalRef<jstring> ContentViewCoreImpl::GetTitle( return ConvertUTF16ToJavaString(env, web_contents()->GetTitle()); } -jdouble ContentViewCoreImpl::GetLoadProgress(JNIEnv* env, jobject obj) const { - // An empty page never loads anything and always has a progress of 0. - // We report 1 in that case so the UI does not assume the page is loading. - if (web_contents()->GetURL().is_empty() || !content_view_client_.get()) - return static_cast<jdouble>(1.0); - return static_cast<jdouble>(content_view_client_->GetLoadProgress()); -} - jboolean ContentViewCoreImpl::IsIncognito(JNIEnv* env, jobject obj) { return web_contents()->GetBrowserContext()->IsOffTheRecord(); } @@ -396,8 +388,6 @@ void ContentViewCoreImpl::SetClient(JNIEnv* env, jobject obj, jobject jclient) { scoped_ptr<ContentViewClient> client( ContentViewClient::CreateNativeContentViewClient(env, jclient)); - web_contents_->SetDelegate(client.get()); - content_view_client_.swap(client); } diff --git a/content/browser/android/content_view_core_impl.h b/content/browser/android/content_view_core_impl.h index a571015..0f659d3 100644 --- a/content/browser/android/content_view_core_impl.h +++ b/content/browser/android/content_view_core_impl.h @@ -106,7 +106,6 @@ class ContentViewCoreImpl : public ContentViewCore, void GoBack(JNIEnv* env, jobject obj); void GoForward(JNIEnv* env, jobject obj); void GoToOffset(JNIEnv* env, jobject obj, jint offset); - jdouble GetLoadProgress(JNIEnv* env, jobject obj) const; void StopLoading(JNIEnv* env, jobject obj); void Reload(JNIEnv* env, jobject obj); jboolean NeedsReload(JNIEnv* env, jobject obj); diff --git a/content/browser/android/ime_utils.cc b/content/browser/android/ime_utils.cc deleted file mode 100644 index 8f173da..0000000 --- a/content/browser/android/ime_utils.cc +++ /dev/null @@ -1,31 +0,0 @@ -// 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 "content/browser/android/ime_utils.h" - -#include <android/input.h> - -#include "base/android/jni_android.h" -#include "content/public/browser/native_web_keyboard_event.h" -#include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h" - -namespace content { - -jobject KeyEventFromNative(const NativeWebKeyboardEvent& event) { - return event.os_event; -} - -NativeWebKeyboardEvent NativeWebKeyboardEventFromKeyEvent( - JNIEnv* env, jobject java_key_event, int action, int modifiers, - long time_ms, int key_code, bool is_system_key, int unicode_char) { - WebKit::WebInputEvent::Type type = WebKit::WebInputEvent::Undefined; - if (action == AKEY_EVENT_ACTION_DOWN) - type = WebKit::WebInputEvent::RawKeyDown; - else if (action == AKEY_EVENT_ACTION_UP) - type = WebKit::WebInputEvent::KeyUp; - return NativeWebKeyboardEvent(java_key_event, type, modifiers, - time_ms, key_code, unicode_char, is_system_key); -} - -} // namespace content diff --git a/content/browser/android/ime_utils.h b/content/browser/android/ime_utils.h deleted file mode 100644 index 87a6e8b..0000000 --- a/content/browser/android/ime_utils.h +++ /dev/null @@ -1,31 +0,0 @@ -// 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 CONTENT_BROWSER_ANDROID_IME_UTILS_H_ -#define CONTENT_BROWSER_ANDROID_IME_UTILS_H_ - -#include <jni.h> - -class AndroidKeyEvent; - -namespace content { - -struct NativeWebKeyboardEvent; - -// Returns a java KeyEvent from a NativeWebKeyboardEvent, NULL if it fails. -jobject KeyEventFromNative(const NativeWebKeyboardEvent& event); - -// Maps a java KeyEvent into a NativeWebKeyboardEvent. -// |java_key_event| is used to maintain a globalref for KeyEvent. -// |action| will help determine the WebInputEvent type. -// type, |modifiers|, |time_ms|, |key_code|, |unicode_char| is used to create -// WebKeyboardEvent. |key_code| is also needed ad need to treat the enter key -// as a key press of character \r. -NativeWebKeyboardEvent NativeWebKeyboardEventFromKeyEvent( - JNIEnv* env, jobject java_key_event, int action, int modifiers, - long time_ms, int key_code, bool is_system_key, int unicode_char); - -} // namespace content - -#endif // CONTENT_BROWSER_ANDROID_IME_UTILS_H_ diff --git a/content/content_browser.gypi b/content/content_browser.gypi index ac06a9d..efc8ab9 100644 --- a/content/content_browser.gypi +++ b/content/content_browser.gypi @@ -202,8 +202,6 @@ 'browser/android/content_settings.h', 'browser/android/content_startup_flags.cc', 'browser/android/content_startup_flags.h', - 'browser/android/content_util.cc', - 'browser/android/content_util.h', 'browser/android/content_video_view.cc', 'browser/android/content_video_view.h', 'browser/android/content_view_client.cc', @@ -218,8 +216,6 @@ 'browser/android/draw_delegate_impl.h', 'browser/android/draw_delegate_impl.cc', 'browser/android/graphics_context.cc', - 'browser/android/ime_utils.cc', - 'browser/android/ime_utils.h', 'browser/android/load_url_params.cc', 'browser/android/load_url_params.h', 'browser/android/sandboxed_process_launcher.cc', diff --git a/content/public/android/java/src/org/chromium/content/browser/ContentView.java b/content/public/android/java/src/org/chromium/content/browser/ContentView.java index a16d389..d39a9e3 100644 --- a/content/public/android/java/src/org/chromium/content/browser/ContentView.java +++ b/content/public/android/java/src/org/chromium/content/browser/ContentView.java @@ -248,13 +248,6 @@ public class ContentView extends FrameLayout implements ContentViewCore.Internal } /** - * @return The load progress of current web contents (range is 0 - 100). - */ - public int getProgress() { - return mContentViewCore.getProgress(); - } - - /** * @return Whether the current WebContents has a previous navigation entry. */ public boolean canGoBack() { diff --git a/content/public/android/java/src/org/chromium/content/browser/ContentViewClient.java b/content/public/android/java/src/org/chromium/content/browser/ContentViewClient.java index af204ac..8f3b2b6 100644 --- a/content/public/android/java/src/org/chromium/content/browser/ContentViewClient.java +++ b/content/public/android/java/src/org/chromium/content/browser/ContentViewClient.java @@ -33,7 +33,6 @@ import java.net.URISyntaxException; * over to WebView. */ public class ContentViewClient { - // Tag used for logging. private static final String TAG = "ContentViewClient"; @@ -74,24 +73,6 @@ public class ContentViewClient { public static final int ERROR_TOO_MANY_REQUESTS = -15; @CalledByNative - public void openNewTab(String url, boolean incognito) { - } - - @CalledByNative - public boolean addNewContents(int nativeSourceWebContents, int nativeWebContents, - int disposition, Rect initialPosition, boolean userGesture) { - return false; - } - - @CalledByNative - public void closeContents() { - } - - @CalledByNative - public void onUrlStarredChanged(boolean starred) { - } - - @CalledByNative public void onPageStarted(String url) { } @@ -100,14 +81,6 @@ public class ContentViewClient { } @CalledByNative - public void onLoadStarted() { - } - - @CalledByNative - public void onLoadStopped() { - } - - @CalledByNative public void onReceivedError(int errorCode, String description, String failingUrl) { } @@ -115,27 +88,10 @@ public class ContentViewClient { public void onMainFrameCommitted(String url, String baseUrl) { } - @CalledByNative - public void onTabHeaderStateChanged() { - } - - @CalledByNative - public void onLoadProgressChanged(double progress) { - } - public void onUpdateTitle(String title) { } @CalledByNative - public void onUpdateUrl(String url) { - } - - @CalledByNative - public void onReceiveFindMatchRects(int version, float[] rect_data, - RectF activeRect) { - } - - @CalledByNative public void onInterstitialShown() { } @@ -143,19 +99,9 @@ public class ContentViewClient { public void onInterstitialHidden() { } - @CalledByNative - public boolean takeFocus(boolean reverse) { - return false; - } - public void onTabCrash(int pid) { } - @CalledByNative - public boolean shouldOverrideUrlLoading(String url) { - return false; - } - public boolean shouldOverrideKeyEvent(KeyEvent event) { int keyCode = event.getKeyCode(); // We need to send almost every key to WebKit. However: @@ -196,20 +142,6 @@ public class ContentViewClient { public void onImeEvent() { } - public void onUnhandledKeyEvent(KeyEvent event) { - // TODO(bulach): we probably want to re-inject the KeyEvent back into - // the system. Investigate if this is at all possible. - } - - @CalledByNative - void handleKeyboardEvent(KeyEvent event) { - onUnhandledKeyEvent(event); - } - - @CalledByNative - public void runFileChooser(FileChooserParams params) { - } - // Return true if the client will handle the JS alert. @CalledByNative public boolean onJsAlert(String url, String Message) { 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 dc4675c..09ac6d4 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 @@ -34,6 +34,7 @@ import org.chromium.content.browser.accessibility.AccessibilityInjector; import org.chromium.content.browser.ContentViewGestureHandler.MotionEventDelegate; /** + * Provides a Java-side 'wrapper' around a WebContent (native) instance. * Contains all the major functionality necessary to manage the lifecycle of a ContentView without * being tied to the view system. */ @@ -336,6 +337,14 @@ public class ContentViewCore implements MotionEventDelegate { } /** + * This is only useful for passing over JNI to native code that requires ContentViewCore*. + * @return native ContentViewCore pointer. + */ + public int getNativeContentViewCore() { + return mNativeContentViewCore; + } + + /** * For internal use. Throws IllegalStateException if mNativeContentView is 0. * Use this to ensure we get a useful Java stack trace, rather than a native * crash dump, from use-after-destroy bugs in Java code. @@ -420,16 +429,6 @@ public class ContentViewCore implements MotionEventDelegate { return null; } - /** - * @return The load progress of current web contents (range is 0 - 100). - */ - public int getProgress() { - if (mNativeContentViewCore != 0) { - return (int) (100.0 * nativeGetLoadProgress(mNativeContentViewCore)); - } - return 100; - } - public int getWidth() { return mContainerView.getWidth(); } @@ -1148,8 +1147,6 @@ public class ContentViewCore implements MotionEventDelegate { private native String nativeGetTitle(int nativeContentViewCoreImpl); - private native double nativeGetLoadProgress(int nativeContentViewCoreImpl); - private native boolean nativeIsIncognito(int nativeContentViewCoreImpl); // Returns true if the native side crashed so that java side can draw a sad tab. diff --git a/content/public/android/java/src/org/chromium/content/browser/FileChooserParams.java b/content/public/android/java/src/org/chromium/content/browser/FileChooserParams.java deleted file mode 100644 index 9868e54..0000000 --- a/content/public/android/java/src/org/chromium/content/browser/FileChooserParams.java +++ /dev/null @@ -1,77 +0,0 @@ -// 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.content.browser; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -/** - * Parameters used by ContentViewClient when a file chooser is to be - * opened. Java equivalent of the native - * content/public/common/file_chooser_params.h, they should be kept in - * sync. See content_util.cc for conversion methods between the Java - * and native types. - */ - -public class FileChooserParams { - // Requires that the file exists before allowing the user to pick it. - public static final int OPEN_MODE = 0; - - // Like Open, but allows picking multiple files to open. - public static final int OPEN_MULTIPLE_MODE = 1; - - // Like Open, but selects a folder. - public static final int OPEN_FOLDER_MODE = 2; - - // Allows picking a nonexistent file, and prompts to overwrite if the file already exists. - public static final int SAVE_MODE = 3; - - private int mMode; - - // Title to be used for the dialog. This may be empty for the default title, which will be - // either "Open" or "Save" depending on the mode. - private String mTitle; - - // Default file name to select in the dialog. - private String mDefaultFileName; - - // A list of valid lower-cased MIME types specified in an input element. It is used to restrict - // selectable files to such types. - private List<String> mAcceptTypes; - - private String mCapture; - - public FileChooserParams(int mode, String title, String defaultFileName, String[] acceptTypes, - String capture) { - mMode = mode; - mTitle = title; - mDefaultFileName = defaultFileName; - mAcceptTypes = Collections.unmodifiableList( - new ArrayList<String>(Arrays.asList(acceptTypes))); - mCapture = capture; - } - - public int getMode() { - return mMode; - } - - public String getTitle() { - return mTitle; - } - - public String getDefaultFileName() { - return mDefaultFileName; - } - - public List<String> getAcceptTypes() { - return mAcceptTypes; - } - - public String getCapture() { - return mCapture; - } -} diff --git a/content/public/browser/web_contents_delegate.cc b/content/public/browser/web_contents_delegate.cc index 34732db..944752c 100644 --- a/content/public/browser/web_contents_delegate.cc +++ b/content/public/browser/web_contents_delegate.cc @@ -135,6 +135,12 @@ bool WebContentsDelegate::ShouldCreateWebContents( return true; } +#if defined(OS_ANDROID) +bool WebContentsDelegate::ShouldOverrideLoading(const GURL& url) { + return false; +} +#endif + JavaScriptDialogCreator* WebContentsDelegate::GetJavaScriptDialogCreator() { return NULL; } diff --git a/content/public/browser/web_contents_delegate.h b/content/public/browser/web_contents_delegate.h index ac817cc..5a339ae 100644 --- a/content/public/browser/web_contents_delegate.h +++ b/content/public/browser/web_contents_delegate.h @@ -307,6 +307,12 @@ class CONTENT_EXPORT WebContentsDelegate { // changed. virtual void ContentRestrictionsChanged(WebContents* source) {} +#if defined(OS_ANDROID) + // Returns true if the delegate wants to handle the url instead. Default + // returns false. + virtual bool ShouldOverrideLoading(const GURL& url); +#endif + // Notification that the tab is hung. virtual void RendererUnresponsive(WebContents* source) {} |