diff options
Diffstat (limited to 'android_webview')
35 files changed, 1615 insertions, 14 deletions
diff --git a/android_webview/DEPS b/android_webview/DEPS index ed3891d..514d673d 100644 --- a/android_webview/DEPS +++ b/android_webview/DEPS @@ -6,7 +6,11 @@ # chrome/ should go into android_webview/lib/ or be refactored. include_rules = [ + # lib is the top-level target, and must remain a leaf in the dependency tree. + "-android_webview/lib", + "+chrome/android/java/src/org/chromium/chrome/browser/component", "+chrome/browser/component", "+content/public", + "+jni", ] diff --git a/android_webview/aw_browser.gypi b/android_webview/aw_browser.gypi new file mode 100644 index 0000000..8153cf8 --- /dev/null +++ b/android_webview/aw_browser.gypi @@ -0,0 +1,11 @@ +# 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. + +{ + 'sources': [ + 'browser/renderer_host/aw_resource_dispatcher_host_delegate.cc', + 'browser/renderer_host/aw_resource_dispatcher_host_delegate.h', + ], +} diff --git a/android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.cc b/android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.cc new file mode 100644 index 0000000..9bf0bc2 --- /dev/null +++ b/android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.cc @@ -0,0 +1,44 @@ +// 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/browser/renderer_host/aw_resource_dispatcher_host_delegate.h" + +#include "base/memory/scoped_ptr.h" +#include "base/memory/scoped_vector.h" +#include "content/public/browser/resource_dispatcher_host.h" +#include "content/public/browser/resource_throttle.h" + +namespace { + +base::LazyInstance<android_webview::AwResourceDispatcherHostDelegate> + g_webview_resource_dispatcher_host_delegate = LAZY_INSTANCE_INITIALIZER; + +} // namespace + +namespace android_webview { + +// static +void AwResourceDispatcherHostDelegate::ResourceDispatcherHostCreated() { + content::ResourceDispatcherHost::Get()->SetDelegate( + &g_webview_resource_dispatcher_host_delegate.Get()); +} + +AwResourceDispatcherHostDelegate::AwResourceDispatcherHostDelegate() + : content::ResourceDispatcherHostDelegate() { +} + +AwResourceDispatcherHostDelegate::~AwResourceDispatcherHostDelegate() { +} + +void AwResourceDispatcherHostDelegate::RequestBeginning( + net::URLRequest* request, + content::ResourceContext* resource_context, + ResourceType::Type resource_type, + int child_id, + int route_id, + bool is_continuation_of_transferred_request, + ScopedVector<content::ResourceThrottle>* throttles) { +} + +} diff --git a/android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.h b/android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.h new file mode 100644 index 0000000..e7e4142 --- /dev/null +++ b/android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.h @@ -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. + +#ifndef ANDROID_WEBVIEW_LIB_RENDERER_HOST_AW_RESOURCE_DISPATCHER_HOST_DELEGATE_H_ +#define ANDROID_WEBVIEW_LIB_RENDERER_HOST_AW_RESOURCE_DISPATCHER_HOST_DELEGATE_H_ + +#include "content/public/browser/resource_dispatcher_host_delegate.h" + +#include "base/lazy_instance.h" + +namespace android_webview { + +class AwResourceDispatcherHostDelegate + : public content::ResourceDispatcherHostDelegate { + public: + static void ResourceDispatcherHostCreated(); + + // Overriden methods from ResourceDispatcherHostDelegate. + virtual void RequestBeginning( + net::URLRequest* request, + content::ResourceContext* resource_context, + ResourceType::Type resource_type, + int child_id, + int route_id, + bool is_continuation_of_transferred_request, + ScopedVector<content::ResourceThrottle>* throttles); + + private: + friend struct base::DefaultLazyInstanceTraits< + AwResourceDispatcherHostDelegate>; + AwResourceDispatcherHostDelegate(); + virtual ~AwResourceDispatcherHostDelegate(); + + DISALLOW_COPY_AND_ASSIGN(AwResourceDispatcherHostDelegate); +}; + +} // namespace android_webview + +#endif // ANDROID_WEBVIEW_LIB_RENDERER_HOST_AW_RESOURCE_DISPATCHER_HOST_H_ diff --git a/android_webview/java/AndroidManifest.xml b/android_webview/java/AndroidManifest.xml new file mode 100644 index 0000000..6079c67 --- /dev/null +++ b/android_webview/java/AndroidManifest.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="utf-8"?> + +<!-- 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. +--> + +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="org.chromium.android_webview"> + +<application android:name="org.chromium.android_webview.test.AndroidWebViewTestRunnerApplication" + android:label="AndroidWebViewTestRunnerApplication" + android:debuggable="true"> + <activity android:name="org.chromium.android_webview.test.AndroidWebViewTestRunnerActivity" + android:label="AndroidWebViewTestRunnerActivity"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" /> + </intent-filter> + </activity> +</application> + + <uses-sdk android:minSdkVersion="16" android:targetSdkVersion="16" /> + <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> + <uses-permission android:name="android.permission.INTERNET"/> + <uses-permission android:name="android.permission.WAKE_LOCK"/> +</manifest> diff --git a/android_webview/java/android_webview_apk.xml b/android_webview/java/android_webview_apk.xml new file mode 100644 index 0000000..8d37948 --- /dev/null +++ b/android_webview/java/android_webview_apk.xml @@ -0,0 +1,45 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + 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. +--> +<project name="AndroidWebView" default="debug" basedir="."> + <description> + Building AndroidWebView.apk + </description> + <import file="../../build/android/ant/common.xml"/> + <import file="../../build/android/ant/sdk-targets.xml"/> + <property-value name="target.abi" value="${APP_ABI}"/> + <property-location name="out.dir" location="${PRODUCT_DIR}/android_webview" + check-exists="false"/> + <property name="resource.absolute.dir" value="../res"/> + <property name="gen.absolute.dir" value="${out.dir}/gen"/> + <property name="jar.libs.dir" value="${out.dir}/java/libs"/> + <property name="native.libs.absolute.dir" location="${out.dir}/libs"/> + <property name="asset.absolute.dir" location="${out.dir}/assets"/> + + <path id="out.dex.jar.input.ref"> + <fileset file="${out.dir}/java/libs/chromium_base.jar"/> + <fileset file="${out.dir}/java/libs/chromium_content.jar"/> + <fileset file="${out.dir}/java/libs/chromium_media.jar"/> + <fileset file="${out.dir}/java/libs/chromium_net.jar"/> + <fileset file="${out.dir}/java/libs/chromium_web_contents_delegate_android.jar"/> + </path> + <property name="java.compilerargs" value="-classpath ${toString:out.dex.jar.input.ref}"/> + + <!-- We expect PRODUCT_DIR to be set like the gyp var (e.g. $ROOT/out/Debug) --> + <fail message="PRODUCT_DIR env var not set?"> + <condition> + <not> + <isset property="PRODUCT_DIR"/> + </not> + </condition> + </fail> + + <!-- Classpath for javac --> + <path id="javac.custom.classpath"> + <path refid="out.dex.jar.input.ref"/> + </path> + <import file="${sdk.dir}/tools/ant/build.xml"/> +</project> diff --git a/android_webview/java/src/org/chromium/android_webview/AndroidWebViewUtil.java b/android_webview/java/src/org/chromium/android_webview/AndroidWebViewUtil.java new file mode 100644 index 0000000..750b338 --- /dev/null +++ b/android_webview/java/src/org/chromium/android_webview/AndroidWebViewUtil.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.android_webview; + +/** + * This class provides a way to create the native WebContents. + */ +public abstract class AndroidWebViewUtil { + // TODO(mkosiba): rename to ContentViewUtil when we stop linking against chrome/ (or share the + // chrome/ ContentViewUtil). + private AndroidWebViewUtil() { + } + + /** + * @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/android_webview/java/src/org/chromium/android_webview/AwContents.java b/android_webview/java/src/org/chromium/android_webview/AwContents.java new file mode 100644 index 0000000..aa94be5 --- /dev/null +++ b/android_webview/java/src/org/chromium/android_webview/AwContents.java @@ -0,0 +1,83 @@ +// 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 android.view.ViewGroup; + +import org.chromium.base.JNINamespace; +import org.chromium.content.browser.ContentViewCore; +import org.chromium.content.common.CleanupReference; + +/** + * Exposes the native AwContents class, and together these classes wrap the ContentViewCore + * and Browser components that are required to implement Android WebView API. This is the + * primary entry point for the WebViewProvider implementation; it holds a 1:1 object + * relationship with application WebView instances. + * (We define this class independent of the hidden WebViewProvider interfaces, to allow + * continuous build & test in the open source SDK-based tree). + */ +@JNINamespace("android_webview") +public class AwContents { + + private int mNativeAwContents; + private ContentViewCore mContentViewCore; + + private static final class DestroyRunnable implements Runnable { + private int mNativeAwContents; + private DestroyRunnable(int nativeAwContents) { + mNativeAwContents = nativeAwContents; + } + @Override + public void run() { + nativeDestroy(mNativeAwContents); + } + } + + private CleanupReference mCleanupReference; + + private AwContents(ContentViewCore contentViewCore, + AwWebContentsDelegate webContentsDelegate) { + } + + /** + * @param containerView the view-hierarchy item this object will be bound to. + * @param internalAccessAdapter to access private methods on containerView. + * @param contentViewCore requires an existing but not yet initialized instance. Will be + * initialized on return. + * @param webContentsDelegate will receive API callbacks from the underlying WebContents + * @param privateBrowsing whether this is a private browsing instance of WebView. + * @param isAccessFromFileURLsGrantedByDefault passed to ContentViewCore.initialize. + */ + public AwContents(ViewGroup containerView, + ContentViewCore.InternalAccessDelegate internalAccessAdapter, + ContentViewCore contentViewCore, AwWebContentsDelegate webContentsDelegate, + boolean privateBrowsing, boolean isAccessFromFileURLsGrantedByDefault) { + mNativeAwContents = nativeInit(webContentsDelegate, privateBrowsing); + mContentViewCore = contentViewCore; + mCleanupReference = new CleanupReference(this, new DestroyRunnable(mNativeAwContents)); + + // TODO: upstream the needed ContentViewCore initialization method. + // mContentViewCore.initialize(containerView, internalAccessAdapter, false, + // nativeGetWebContents(mNativeAwContents), isAccessFromFileURLsGrantedByDefault); + } + + public ContentViewCore getContentViewCore() { + return mContentViewCore; + } + + public void destroy() { + if (mContentViewCore != null) { + mContentViewCore.destroy(); + mContentViewCore = null; + } + mCleanupReference.cleanupNow(); + } + + private native int nativeInit(AwWebContentsDelegate webViewWebContentsDelegate, + boolean privateBrowsing); + private static native void nativeDestroy(int nativeAwContents); + + private native int nativeGetWebContents(int nativeAwContents); +} diff --git a/android_webview/java/src/org/chromium/android_webview/InterceptedRequestData.java b/android_webview/java/src/org/chromium/android_webview/InterceptedRequestData.java new file mode 100644 index 0000000..2a5460e --- /dev/null +++ b/android_webview/java/src/org/chromium/android_webview/InterceptedRequestData.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 java.io.InputStream; + +/** + * The response information that is to be returned for a particular resource fetch. + */ +public class InterceptedRequestData { + private String mMimeType; + private String mCharset; + private InputStream mData; + + public InterceptedRequestData(String mimeType, String encoding, InputStream data) { + mMimeType = mimeType; + mCharset = encoding; + mData = data; + } + + @CalledByNative + public String getMimeType() { + return mMimeType; + } + + @CalledByNative + public String getCharset() { + return mCharset; + } + + @CalledByNative + public InputStream getData() { + return mData; + } +} diff --git a/android_webview/javatests/AndroidManifest.xml b/android_webview/javatests/AndroidManifest.xml new file mode 100644 index 0000000..1151d87 --- /dev/null +++ b/android_webview/javatests/AndroidManifest.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="utf-8"?> + <!-- 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 name must be unique so suffix with "tests" so package loader + doesn't ignore this. --> + <manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="org.chromium.android_webview.tests"> + <!-- We add an application tag here just so that we can indicate that this + package needs to link against the android.test library, which is + needed when building test cases. --> + <application> + <uses-library android:name="android.test.runner" /> + </application> + <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="14" /> + <instrumentation android:name="android.test.InstrumentationTestRunner" + android:targetPackage="org.chromium.android_webview" + android:label="Tests for org.chromium.android_webview"/> + <uses-permission android:name="android.permission.RUN_INSTRUMENTATION" /> + <uses-permission android:name="android.permission.INJECT_EVENTS" /> + <uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" /> + <uses-permission android:name="android.permission.READ_LOGS"/> + <uses-permission android:name="android.permission.WAKE_LOCK" /> +</manifest> diff --git a/android_webview/javatests/DEPS b/android_webview/javatests/DEPS new file mode 100644 index 0000000..7abdb00 --- /dev/null +++ b/android_webview/javatests/DEPS @@ -0,0 +1,4 @@ +include_rules = [ + # Temporary until we move all common test code to content/public/android. + "!content/android/javatests", +] diff --git a/android_webview/javatests/android_webview_test_apk.xml b/android_webview/javatests/android_webview_test_apk.xml new file mode 100644 index 0000000..bee7eac --- /dev/null +++ b/android_webview/javatests/android_webview_test_apk.xml @@ -0,0 +1,55 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + 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. +--> +<project name="AndroidWebViewTest" default="debug" basedir="."> + + <description> + Building AndroidWebViewTest.apk + </description> + + <import file="../../build/android/ant/common.xml"/> + <import file="../../build/android/ant/sdk-targets.xml"/> + <property name="target.abi" value="${APP_ABI}"/> + <property name="out.dir" location="${PRODUCT_DIR}/android_webview_test"/> + <property name="resource.absolute.dir" value="../res"/> + <property name="gen.absolute.dir" value="${out.dir}/gen"/> + <property name="native.libs.absolute.dir" location="${out.dir}/libs" /> + <property name="asset.absolute.dir" location="${out.dir}/assets" /> + + <path id="out.dex.jar.input.ref"> + <fileset dir="${PRODUCT_DIR}/android_webview_test/java/libs"/> + </path> + <property name="java.compilerargs" value="-classpath ${toString:out.dex.jar.input.ref}"/> + + <!-- We expect PRODUCT_DIR to be set like the gyp var + (e.g. $ROOT/out/Debug) --> + <fail message="PRODUCT_DIR env var not set?"> + <condition> + <not> + <isset property="PRODUCT_DIR"/> + </not> + </condition> + </fail> + + <target name="-post-compile"> + <!-- We also want a .jar as well as an .apk for AndroidWebViewTest-debug + so that proguard can be used to list the tests by annotation. --> + <jar destfile="${out.dir}/${ant.project.name}-debug.jar"> + <fileset dir="${out.dir}/classes" includes="**/*.class"/> + <zipfileset + includes="**/*.class" + src="${PRODUCT_DIR}/android_webview/java/libs/chromium_android_webview_javatests.jar"/> + </jar> + + </target> + + <!-- Classpath for javac --> + <path id="javac.custom.classpath"> + <path refid="out.dex.jar.input.ref"/> + </path> + <import file="${sdk.dir}/tools/ant/build.xml" /> + +</project> diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AndroidWebViewLoadUrlTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AndroidWebViewLoadUrlTest.java new file mode 100644 index 0000000..a78d519 --- /dev/null +++ b/android_webview/javatests/src/org/chromium/android_webview/test/AndroidWebViewLoadUrlTest.java @@ -0,0 +1,72 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.android_webview.test; + +import android.test.suitebuilder.annotation.Smoke; +import android.test.suitebuilder.annotation.SmallTest; + +import org.chromium.base.test.Feature; +import org.chromium.content.browser.ContentView; +import org.chromium.content.browser.ContentViewCore; +import org.chromium.content.browser.test.TestContentViewClient; + +import java.util.concurrent.Callable; +import java.util.concurrent.atomic.AtomicReference; +import java.util.ArrayList; + +/** + * Test suite for loadUrl(). + */ +public class AndroidWebViewLoadUrlTest extends AndroidWebViewTestBase { + + private ContentViewCore createContentViewOnMainSync(final TestContentViewClient client) + throws Exception { + final AtomicReference<ContentView> contentView = new AtomicReference<ContentView>(); + getInstrumentation().runOnMainSync(new Runnable() { + @Override + public void run() { + contentView.set(createContentView(false, client)); + getActivity().setContentViews(contentView.get()); + } + }); + return contentView.get().getContentViewCore(); + } + + private String getTitleOnUiThread(final ContentViewCore contentViewCore) throws Throwable { + return runTestOnUiThreadAndGetResult(new Callable<String>() { + @Override + public String call() throws Exception { + return contentViewCore.getTitle(); + } + }); + } + + @SmallTest + @Feature({"Android-WebView"}) + public void testDataUrl() throws Throwable { + final String expectedTitle = "dataUrlTest"; + final String dataUrl = + "data:text/html,<html><head><title>" + expectedTitle + "</title></head></html>"; + + final TestContentViewClient contentViewClient = new TestContentViewClient(); + final ContentViewCore contentViewCore = createContentViewOnMainSync(contentViewClient); + loadUrlSync(contentViewCore, contentViewClient.getOnPageFinishedHelper(), dataUrl); + assertEquals(expectedTitle, getTitleOnUiThread(contentViewCore)); + } + + @SmallTest + @Feature({"Android-WebView"}) + public void testDataUrlBase64() throws Throwable { + final String expectedTitle = "dataUrlTestBase64"; + final String dataUrl = "data:text/html;base64," + + "PGh0bWw+PGhlYWQ+PHRpdGxlPmRhdGFVcmxUZXN0QmFzZTY0PC90aXRsZT48" + + "L2hlYWQ+PC9odG1sPg=="; + + final TestContentViewClient contentViewClient = new TestContentViewClient(); + final ContentViewCore contentViewCore = createContentViewOnMainSync(contentViewClient); + loadUrlSync(contentViewCore, contentViewClient.getOnPageFinishedHelper(), dataUrl); + assertEquals(expectedTitle, getTitleOnUiThread(contentViewCore)); + } +} 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 new file mode 100644 index 0000000..56b909a --- /dev/null +++ b/android_webview/javatests/src/org/chromium/android_webview/test/AndroidWebViewTestBase.java @@ -0,0 +1,134 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.android_webview.test; + +import android.app.Instrumentation; +import android.content.Context; +import android.test.ActivityInstrumentationTestCase2; +import android.view.View; + +import org.chromium.android_webview.AndroidWebViewUtil; +import org.chromium.android_webview.AwContents; +import org.chromium.content.browser.ContentSettings; +import org.chromium.content.browser.ContentView; +import org.chromium.content.browser.ContentViewClient; +import org.chromium.content.browser.ContentViewCore; +import org.chromium.content.browser.LoadUrlParams; +import org.chromium.content.browser.test.CallbackHelper; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.FutureTask; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +/** + * A base class for android_webview tests. + */ +public class AndroidWebViewTestBase + extends ActivityInstrumentationTestCase2<AndroidWebViewTestRunnerActivity> { + protected static int WAIT_TIMEOUT_SECONDS = 15; + + public AndroidWebViewTestBase() { + super(AndroidWebViewTestRunnerActivity.class); + } + + @Override + protected void setUp() throws Exception { + final Context context = getActivity(); + getInstrumentation().runOnMainSync(new Runnable() { + @Override + public void run() { + ContentViewCore.initChromiumBrowserProcess( + context, ContentView.MAX_RENDERERS_SINGLE_PROCESS); + } + }); + } + + /** + * Runs a {@link Callable} on the main thread, blocking until it is + * complete, and returns the result. Calls + * {@link Instrumentation#waitForIdleSync()} first to help avoid certain + * race conditions. + * + * @param <R> Type of result to return + */ + public <R> R runTestOnUiThreadAndGetResult(Callable<R> callable) + throws Throwable { + FutureTask<R> task = new FutureTask<R>(callable); + getInstrumentation().waitForIdleSync(); + getInstrumentation().runOnMainSync(task); + try { + return task.get(); + } catch (ExecutionException e) { + // Unwrap the cause of the exception and re-throw it. + throw e.getCause(); + } + } + + /** + * Loads url on the UI thread and blocks until onPageFinished is called. + */ + protected void loadUrlSync(final ContentViewCore contentViewCore, + CallbackHelper onPageFinishedHelper, + final String url) throws Throwable { + int currentCallCount = onPageFinishedHelper.getCallCount(); + loadUrlAsync(contentViewCore, url); + onPageFinishedHelper.waitForCallback(currentCallCount, 1, WAIT_TIMEOUT_SECONDS, + TimeUnit.SECONDS); + } + + /** + * Loads url on the UI thread but does not block. + */ + protected void loadUrlAsync(final ContentViewCore contentViewCore, + final String url) throws Throwable { + runTestOnUiThread(new Runnable() { + @Override + public void run() { + contentViewCore.loadUrl(new LoadUrlParams(url)); + } + }); + } + + /** + * Loads data on the UI thread and blocks until onPageFinished is called. + */ + protected void loadDataSync(final ContentViewCore contentViewCore, + CallbackHelper onPageFinishedHelper, + final String data, final String mimeType, + final boolean isBase64Encoded) throws Throwable { + int currentCallCount = onPageFinishedHelper.getCallCount(); + loadDataAsync(contentViewCore, data, mimeType, isBase64Encoded); + onPageFinishedHelper.waitForCallback(currentCallCount, 1, WAIT_TIMEOUT_SECONDS, + TimeUnit.SECONDS); + } + + /** + * Loads data on the UI thread but does not block. + */ + protected void loadDataAsync(final ContentViewCore contentViewCore, final String data, + final String mimeType, final boolean isBase64Encoded) + throws Throwable { + runTestOnUiThread(new Runnable() { + @Override + public void run() { + contentViewCore.loadUrl(LoadUrlParams.createLoadDataParams( + data, mimeType, isBase64Encoded)); + } + }); + } + + protected ContentView createContentView(boolean incognito, + ContentViewClient contentViewClient) { + int nativeWebContents = AndroidWebViewUtil.createNativeWebContents(incognito); + ContentView contentView = ContentView.newInstance(getActivity(), nativeWebContents, + ContentView.PERSONALITY_VIEW); + contentView.setContentViewClient(contentViewClient); + return contentView; + } +} diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AndroidWebViewTestRunnerActivity.java b/android_webview/javatests/src/org/chromium/android_webview/test/AndroidWebViewTestRunnerActivity.java new file mode 100644 index 0000000..4d78a6a --- /dev/null +++ b/android_webview/javatests/src/org/chromium/android_webview/test/AndroidWebViewTestRunnerActivity.java @@ -0,0 +1,94 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.android_webview.test; + +import android.app.Activity; +import android.content.ContentUris; +import android.content.res.Configuration; +import android.os.Bundle; +import android.util.Log; +import android.view.ViewGroup.LayoutParams; +import android.view.WindowManager; +import android.widget.LinearLayout; + +import org.chromium.content.browser.ContentView; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/* + * This is a lightweight activity for tests that only require ContentView functionality. + */ +public class AndroidWebViewTestRunnerActivity extends Activity { + + private LinearLayout mLinearLayout; + private List<ContentView> mContentViews = new ArrayList<ContentView>(); + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + // TODO(joth): When SW-renderer is available, we'll want to enable this on a per-test + // basis. + // BUG=http://b/5996811 + boolean hardwareAccelerated = true; + Log.i("AndroidWebViewTestRunnerActivity", "Is " + (hardwareAccelerated ? "" : "NOT ") + + "hardware accelerated"); + + if (hardwareAccelerated) { + getWindow().setFlags( + WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED, + WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED); + } + + mLinearLayout = new LinearLayout(this); + mLinearLayout.setOrientation(LinearLayout.VERTICAL); + mLinearLayout.setShowDividers(LinearLayout.SHOW_DIVIDER_MIDDLE); + mLinearLayout.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, + LayoutParams.WRAP_CONTENT)); + + setContentView(mLinearLayout); + } + + /** + * Set the ContentViews to be added to the current LinearLayout. + * + * This will destroy the ContentView instances that are being removed from the LinearLayout, so + * care must be taken to not reference those instances. + */ + public void setContentViewList(Collection<ContentView> contentViews) { + mLinearLayout.removeAllViews(); + + Set<ContentView> toBeDeleted = new HashSet<ContentView>(mContentViews); + toBeDeleted.removeAll(contentViews); + for (ContentView c : toBeDeleted) { + c.destroy(); + } + + for (ContentView c : contentViews) { + c.setLayoutParams(new LinearLayout.LayoutParams( + LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT, 1f)); + mLinearLayout.addView(c); + } + mContentViews.clear(); + mContentViews.addAll(contentViews); + } + + public void setContentViews(ContentView... contentViews) { + setContentViewList(Arrays.asList(contentViews)); + } + + public int getNumberOfContentViews() { + return mContentViews.size(); + } + + public ContentView getContentView() { + return mContentViews.get(0); + } +} diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AndroidWebViewTestRunnerApplication.java b/android_webview/javatests/src/org/chromium/android_webview/test/AndroidWebViewTestRunnerApplication.java new file mode 100644 index 0000000..7fb1d4c --- /dev/null +++ b/android_webview/javatests/src/org/chromium/android_webview/test/AndroidWebViewTestRunnerApplication.java @@ -0,0 +1,46 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.android_webview.test; + +import android.app.Application; + +import org.chromium.base.PathUtils; +import org.chromium.content.app.LibraryLoader; +import org.chromium.content.browser.ResourceExtractor; +import org.chromium.content.common.CommandLine; + +import android.util.Log; + +public class AndroidWebViewTestRunnerApplication extends Application { + + /** + * The name of the library to load. + */ + private static final String NATIVE_LIBRARY = "webview"; + + /** The minimum set of .pak files Chrome needs. */ + private static final String[] CHROME_MANDATORY_PAKS = { + "chrome.pak", "chrome_100_percent.pak", "en-US.pak", "resources.pak", + }; + + private static final String PRIVATE_DATA_DIRECTORY_SUFFIX = "webview"; + + @Override + public void onCreate() { + super.onCreate(); + initializeApplicationParameters(); + } + + /** Handles initializing the common application parameters. */ + private static void initializeApplicationParameters() { + CommandLine.initFromFile("/data/local/tmp/chrome-command-line"); + PathUtils.setPrivateDataDirectorySuffix(PRIVATE_DATA_DIRECTORY_SUFFIX); + // We don't need to extract any paks because for WebView, they are + // in the system image. + ResourceExtractor.setMandatoryPaksToExtract(CHROME_MANDATORY_PAKS); + LibraryLoader.setLibraryToLoad(NATIVE_LIBRARY); + LibraryLoader.loadAndInitSync(); + } +} diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsTest.java new file mode 100644 index 0000000..ff88c3b --- /dev/null +++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsTest.java @@ -0,0 +1,64 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.android_webview.test; + +import android.content.Context; +import android.os.Handler; +import android.os.Looper; +import android.test.suitebuilder.annotation.SmallTest; +import android.view.View; +import android.widget.GridLayout; + +import org.chromium.android_webview.AndroidWebViewUtil; +import org.chromium.android_webview.AwContents; +import org.chromium.android_webview.AwWebContentsDelegate; +import org.chromium.base.test.Feature; +import org.chromium.content.browser.ContentViewCore; + +import java.util.concurrent.Semaphore; +import java.util.concurrent.TimeUnit; + +/** + * AwContents tests. + */ +public class AwContentsTest extends AndroidWebViewTestBase { + private AwWebContentsDelegate mAwWebContentsDelegate = + new AwWebContentsDelegate(); + + private AwContents createContents(Context context) { + GridLayout viewGroup = new GridLayout(context); + + ContentViewCore contentViewCore = new ContentViewCore( + context, viewGroup, null, 0, ContentViewCore.PERSONALITY_VIEW); + AwContents awContents = new AwContents(viewGroup, null, contentViewCore, + mAwWebContentsDelegate, false, false); + return awContents; + } + + @SmallTest + public void testCreateDestroy() throws Throwable { + final Throwable[] error = new Throwable[1]; + final Semaphore s = new Semaphore(0); + final Context context = getActivity(); + + Runnable r = new Runnable() { + @Override + public void run() { + try { + createContents(context).destroy(); + } catch (Throwable t) { + error[0] = t; + } finally { + s.release(); + } + } + }; + new Handler(Looper.getMainLooper()).post(r); + assertTrue(s.tryAcquire(10000, TimeUnit.MILLISECONDS)); + if (error[0] != null) { + throw error[0]; + } + } +} diff --git a/android_webview/lib/DEPS b/android_webview/lib/DEPS index 2dc7f40..6324617 100644 --- a/android_webview/lib/DEPS +++ b/android_webview/lib/DEPS @@ -15,5 +15,16 @@ include_rules = [ "!chrome/browser/android/tab_android.h", # Temporary until autofill becomes a browser component. - "!chrome/browser/autofill/autofill_external_delegate.h" + "!chrome/browser/autofill/autofill_external_delegate.h", + + # Temporary until we implement our own versions of the *Client classes. + "!chrome/browser/browser_process.h", + "!chrome/browser/profiles/profile.h", + "!chrome/browser/profiles/profile_manager.h", + + # Temporary until the javascript dialog creator is unpicked from WebView. + "!chrome/browser/ui/app_modal_dialogs/javascript_dialog_creator.h", + + # Temporarily required until we instantiate components individually. + "!chrome/browser/ui/tab_contents/tab_contents.h", ] diff --git a/android_webview/lib/android_webview.gyp b/android_webview/lib/android_webview.gyp index 8cd34ee..aea913f 100644 --- a/android_webview/lib/android_webview.gyp +++ b/android_webview/lib/android_webview.gyp @@ -10,21 +10,30 @@ 'target_name': 'libwebview', 'type': 'shared_library', 'dependencies': [ - '../../chrome/chrome.gyp:browser', - '../../chrome/chrome.gyp:renderer', - '../../content/content.gyp:content', - '../native/webview_native.gyp:webview_native', + '<(DEPTH)/chrome/chrome.gyp:browser', + '<(DEPTH)/chrome/chrome.gyp:renderer', + '<(DEPTH)/content/content.gyp:content', + '<(DEPTH)/android_webview/native/webview_native.gyp:webview_native', + '<(DEPTH)/chrome/browser/component/components.gyp:web_contents_delegate_android', + '<(DEPTH)/chrome/browser/component/components.gyp:browser_component_jni_headers', ], 'include_dirs': [ '../..', '../../skia/config', ], 'sources': [ + 'aw_browser_dependency_factory_impl.cc', + 'aw_browser_dependency_factory_impl.h', + 'aw_content_browser_client.cc', + 'aw_content_browser_client.h', 'main/webview_entry_point.cc', 'main/webview_main_delegate.cc', 'main/webview_main_delegate.h', 'main/webview_stubs.cc', ], + 'includes': [ + '../aw_browser.gypi', + ], }, { 'target_name': 'android_webview', @@ -54,11 +63,240 @@ }, ], }, + { + 'target_name': 'android_webview_java', + 'type': 'none', + 'dependencies': [ + '<(DEPTH)/content/content.gyp:content_java', + '<(DEPTH)/chrome/browser/component/components.gyp:web_contents_delegate_android_java', + ], + 'variables': { + 'package_name': 'android_webview_java', + 'java_in_dir': '<(DEPTH)/android_webview/java', + }, + 'includes': [ '../../build/java.gypi' ], + }, + { + 'target_name': 'android_webview_javatests', + 'type': 'none', + 'dependencies': [ + 'android_webview_java', + '<(DEPTH)/base/base.gyp:base_java_test_support', + '<(DEPTH)/content/content.gyp:content_java', + '<(DEPTH)/content/content.gyp:content_javatests', + '<(DEPTH)/chrome/browser/component/components.gyp:web_contents_delegate_android_java', + ], + 'variables': { + 'package_name': 'android_webview_javatests', + 'java_in_dir': '<(DEPTH)/android_webview/javatests', + }, + 'includes': [ '../../build/java.gypi' ], + }, + + { + 'target_name': 'android_webview_apk', + 'type': 'none', + 'actions': [ + { + 'action_name': 'copy_base_jar', + 'inputs': ['<(PRODUCT_DIR)/lib.java/chromium_base.jar'], + 'outputs': ['<(PRODUCT_DIR)/android_webview/java/libs/chromium_base.jar'], + 'action': ['cp', '<@(_inputs)', '<@(_outputs)'], + }, + { + 'action_name': 'copy_net_jar', + 'inputs': ['<(PRODUCT_DIR)/lib.java/chromium_net.jar'], + 'outputs': ['<(PRODUCT_DIR)/android_webview/java/libs/chromium_net.jar'], + 'action': ['cp', '<@(_inputs)', '<@(_outputs)'], + }, + { + 'action_name': 'copy_media_jar', + 'inputs': ['<(PRODUCT_DIR)/lib.java/chromium_media.jar'], + 'outputs': ['<(PRODUCT_DIR)/android_webview/java/libs/chromium_media.jar'], + 'action': ['cp', '<@(_inputs)', '<@(_outputs)'], + }, + { + 'action_name': 'copy_content_jar', + 'inputs': ['<(PRODUCT_DIR)/lib.java/chromium_content.jar'], + 'outputs': ['<(PRODUCT_DIR)/android_webview/java/libs/chromium_content.jar'], + 'action': ['cp', '<@(_inputs)', '<@(_outputs)'], + }, + { + 'action_name': 'copy_web_contents_delegate_android_java', + 'inputs': ['<(PRODUCT_DIR)/lib.java/chromium_web_contents_delegate_android.jar'], + 'outputs': ['<(PRODUCT_DIR)/android_webview/java/libs/chromium_web_contents_delegate_android.jar'], + 'action': ['cp', '<@(_inputs)', '<@(_outputs)'], + }, + { + 'action_name': 'copy_android_webview_jar', + 'inputs': ['<(PRODUCT_DIR)/lib.java/chromium_android_webview_java.jar'], + 'outputs': ['<(PRODUCT_DIR)/android_webview/java/libs/chromium_android_webview_java.jar'], + 'action': ['cp', '<@(_inputs)', '<@(_outputs)'], + }, + { + 'action_name': 'copy_android_webview_test_jar', + 'inputs': ['<(PRODUCT_DIR)/lib.java/chromium_android_webview_javatests.jar'], + 'outputs': ['<(PRODUCT_DIR)/android_webview/java/libs/chromium_android_webview_javatests.jar'], + 'action': ['cp', '<@(_inputs)', '<@(_outputs)'], + }, + { + 'action_name': 'copy_chrome_pak', + 'inputs': ['<(SHARED_INTERMEDIATE_DIR)/repack/chrome.pak'], + 'outputs': ['<(PRODUCT_DIR)/android_webview/assets/chrome.pak'], + 'action': ['cp', '<@(_inputs)', '<@(_outputs)'], + }, + { + 'action_name': 'copy_chrome_100_percent_pak', + 'inputs': ['<(SHARED_INTERMEDIATE_DIR)/repack/chrome_100_percent.pak'], + 'outputs': ['<(PRODUCT_DIR)/android_webview/assets/chrome_100_percent.pak'], + 'action': ['cp', '<@(_inputs)', '<@(_outputs)'], + }, + { + 'action_name': 'copy_resources_pak', + 'inputs': ['<(SHARED_INTERMEDIATE_DIR)/repack/resources.pak'], + 'outputs': ['<(PRODUCT_DIR)/android_webview/assets/resources.pak'], + 'action': ['cp', '<@(_inputs)', '<@(_outputs)'], + }, + { + 'action_name': 'copy_en_pak', + 'inputs': ['<(SHARED_INTERMEDIATE_DIR)/repack/en-US.pak'], + 'outputs': ['<(PRODUCT_DIR)/android_webview/assets/en.pak'], + 'action': ['cp', '<@(_inputs)', '<@(_outputs)'], + }, + { + 'action_name': 'copy_and_strip_so', + 'inputs': ['<(SHARED_LIB_DIR)/libwebview.so'], + 'outputs': ['<(PRODUCT_DIR)/android_webview/libs/<(android_app_abi)/libwebview.so'], + 'action': [ + '<!(/bin/echo -n $STRIP)', + '--strip-unneeded', # All symbols not needed for relocation. + '<@(_inputs)', + '-o', + '<@(_outputs)', + ], + }, + { + 'action_name': 'android_webview_apk', + 'inputs': [ + '<(DEPTH)/android_webview/java/android_webview_apk.xml', + '<(DEPTH)/android_webview/java/AndroidManifest.xml', + '<(PRODUCT_DIR)/android_webview/java/libs/chromium_android_webview_java.jar', + '<(PRODUCT_DIR)/android_webview/java/libs/chromium_android_webview_javatests.jar', + '<(PRODUCT_DIR)/android_webview/java/libs/chromium_base.jar', + '<(PRODUCT_DIR)/android_webview/java/libs/chromium_net.jar', + '<(PRODUCT_DIR)/android_webview/java/libs/chromium_media.jar', + '<(PRODUCT_DIR)/android_webview/java/libs/chromium_content.jar', + '<(SHARED_INTERMEDIATE_DIR)/repack/chrome.pak', + '<(SHARED_INTERMEDIATE_DIR)/repack/chrome_100_percent.pak', + '<(SHARED_INTERMEDIATE_DIR)/repack/resources.pak', + '<(SHARED_INTERMEDIATE_DIR)/repack/en-US.pak', + '<(PRODUCT_DIR)/android_webview/libs/<(android_app_abi)/libwebview.so', + ], + 'outputs': [ + '<(PRODUCT_DIR)/android_webview/AndroidWebView-debug.apk', + ], + 'action': [ + 'ant', + '-DPRODUCT_DIR=<(ant_build_out)', + '-DAPP_ABI=<(android_app_abi)', + '-DANDROID_SDK=<(android_sdk)', + '-DANDROID_SDK_ROOT=<(android_sdk_root)', + '-DANDROID_SDK_TOOLS=<(android_sdk_tools)', + '-DANDROID_SDK_VERSION=<(android_sdk_version)', + '-DANDROID_TOOLCHAIN=<(android_toolchain)', + '-buildfile', + '<(DEPTH)/android_webview/java/android_webview_apk.xml', + ], + 'dependencies': [ + 'libwebview', + 'android_webview_java', + 'android_webview_javatests', + '<(DEPTH)/chrome/chrome_resources.gyp:packed_resources', + '<(DEPTH)/chrome/chrome_resources.gyp:packed_extra_resources', + ], + } + ], + }, + { + 'target_name': 'android_webview_test_apk', + 'type': 'none', + 'dependencies': [ + 'android_webview_apk', + '<(DEPTH)/content/content.gyp:content_javatests', + ], + 'actions': [ + { + 'action_name': 'copy_base_jar', + 'inputs': ['<(PRODUCT_DIR)/lib.java/chromium_base.jar'], + 'outputs': ['<(PRODUCT_DIR)/android_webview_test/java/libs/chromium_base.jar'], + 'action': ['cp', '<@(_inputs)', '<@(_outputs)'], + }, + { + 'action_name': 'copy_base_javatests_jar', + 'inputs': ['<(PRODUCT_DIR)/lib.java/chromium_base_javatests.jar'], + 'outputs': ['<(PRODUCT_DIR)/android_webview_test/java/libs/chromium_base_javatests.jar'], + 'action': ['cp', '<@(_inputs)', '<@(_outputs)'], + }, + { + 'action_name': 'copy_net_jar', + 'inputs': ['<(PRODUCT_DIR)/lib.java/chromium_net.jar'], + 'outputs': ['<(PRODUCT_DIR)/android_webview_test/java/libs/chromium_net.jar'], + 'action': ['cp', '<@(_inputs)', '<@(_outputs)'], + }, + { + 'action_name': 'copy_media_jar', + 'inputs': ['<(PRODUCT_DIR)/lib.java/chromium_media.jar'], + 'outputs': ['<(PRODUCT_DIR)/android_webview_test/java/libs/chromium_media.jar'], + 'action': ['cp', '<@(_inputs)', '<@(_outputs)'], + }, + { + 'action_name': 'copy_content_jar', + 'inputs': ['<(PRODUCT_DIR)/lib.java/chromium_content.jar'], + 'outputs': ['<(PRODUCT_DIR)/android_webview_test/java/libs/chromium_content.jar'], + 'action': ['cp', '<@(_inputs)', '<@(_outputs)'], + }, + { + 'action_name': 'copy_web_contents_delegate_android_java', + 'inputs': ['<(PRODUCT_DIR)/lib.java/chromium_web_contents_delegate_android.jar'], + 'outputs': ['<(PRODUCT_DIR)/android_webview_test/java/libs/chromium_web_contents_delegate_android.jar'], + 'action': ['cp', '<@(_inputs)', '<@(_outputs)'], + }, + { + 'action_name': 'copy_content_javatests_jar', + 'inputs': ['<(PRODUCT_DIR)/lib.java/chromium_content_javatests.jar'], + 'outputs': ['<(PRODUCT_DIR)/android_webview_test/java/libs/chromium_content_javatests.jar'], + 'action': ['cp', '<@(_inputs)', '<@(_outputs)'], + }, + { + 'action_name': 'copy_android_webview_jar', + 'inputs': ['<(PRODUCT_DIR)/lib.java/chromium_android_webview_java.jar'], + 'outputs': ['<(PRODUCT_DIR)/android_webview_test/java/libs/chromium_android_webview_java.jar'], + 'action': ['cp', '<@(_inputs)', '<@(_outputs)'], + }, + { + 'action_name': 'android_webview_test_generate_apk', + 'inputs': [ + '<(DEPTH)/android_webview/javatests/android_webview_test_apk.xml', + '<(DEPTH)/android_webview/javatests/AndroidManifest.xml', + '<!@(find <(DEPTH)/android_webview/javatests/ -name "*.java")' + ], + 'outputs': [ + '<(PRODUCT_DIR)/android_webview_test/ContentShellTest-debug.apk', + ], + 'action': [ + 'ant', + '-DPRODUCT_DIR=<(ant_build_out)', + '-DAPP_ABI=<(android_app_abi)', + '-DANDROID_SDK=<(android_sdk)', + '-DANDROID_SDK_ROOT=<(android_sdk_root)', + '-DANDROID_SDK_TOOLS=<(android_sdk_tools)', + '-DANDROID_SDK_VERSION=<(android_sdk_version)', + '-DANDROID_TOOLCHAIN=<(android_toolchain)', + '-buildfile', + '<(DEPTH)/android_webview/javatests/android_webview_test_apk.xml', + ] + } + ], + }, ], } - -# Local Variables: -# tab-width:2 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=2 shiftwidth=2: diff --git a/android_webview/lib/aw_browser_dependency_factory_impl.cc b/android_webview/lib/aw_browser_dependency_factory_impl.cc new file mode 100644 index 0000000..6865efc --- /dev/null +++ b/android_webview/lib/aw_browser_dependency_factory_impl.cc @@ -0,0 +1,70 @@ +// 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/lib/aw_browser_dependency_factory_impl.h" + +// TODO(joth): Componentize or remove chrome/... dependencies. +#include "android_webview/native/aw_contents_container.h" +#include "base/lazy_instance.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/profiles/profile_manager.h" +#include "chrome/browser/ui/app_modal_dialogs/javascript_dialog_creator.h" +#include "chrome/browser/ui/tab_contents/tab_contents.h" +#include "content/public/browser/web_contents.h" +#include "ipc/ipc_message.h" + +namespace android_webview { + +namespace { + +base::LazyInstance<AwBrowserDependencyFactoryImpl>::Leaky g_lazy_instance; + +class TabContentsWrapper : public AwContentsContainer { + public: + TabContentsWrapper(content::WebContents* web_contents) + : tab_contents_(web_contents) {} + virtual ~TabContentsWrapper() {} + + // AwContentsContainer + virtual content::WebContents* GetWebContents() OVERRIDE { + return tab_contents_.web_contents(); + } + + private: + TabContents tab_contents_; +}; + +} // namespace + +AwBrowserDependencyFactoryImpl::AwBrowserDependencyFactoryImpl() {} + +AwBrowserDependencyFactoryImpl::~AwBrowserDependencyFactoryImpl() {} + +// static +void AwBrowserDependencyFactoryImpl::InstallInstance() { + SetInstance(g_lazy_instance.Pointer()); +} + +content::WebContents* +AwBrowserDependencyFactoryImpl::CreateWebContents(bool incognito) { + Profile* profile = g_browser_process->profile_manager()->GetDefaultProfile(); + if (incognito) + profile = profile->GetOffTheRecordProfile(); + + return content::WebContents::Create(profile, 0, MSG_ROUTING_NONE, 0); +} + +AwContentsContainer* AwBrowserDependencyFactoryImpl::CreateContentsContainer( + content::WebContents* contents) { + return new TabContentsWrapper(contents); +} + +content::JavaScriptDialogCreator* + AwBrowserDependencyFactoryImpl::GetJavaScriptDialogCreator() { + return GetJavaScriptDialogCreatorInstance(); +} + +} // namespace android_webview + diff --git a/android_webview/lib/aw_browser_dependency_factory_impl.h b/android_webview/lib/aw_browser_dependency_factory_impl.h new file mode 100644 index 0000000..fae835f --- /dev/null +++ b/android_webview/lib/aw_browser_dependency_factory_impl.h @@ -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. + +#ifndef ANDROID_WEBVIEW_LIB_BROWSER_DELEGATE_IMPL_H_ +#define ANDROID_WEBVIEW_LIB_BROWSER_DELEGATE_IMPL_H_ + +#include "android_webview/native/aw_browser_dependency_factory.h" + +#include "base/compiler_specific.h" + +namespace android_webview { + +class AwBrowserDependencyFactoryImpl : public AwBrowserDependencyFactory { + public: + AwBrowserDependencyFactoryImpl(); + virtual ~AwBrowserDependencyFactoryImpl(); + + // Sets this class as the singleton instance. + static void InstallInstance(); + + // AwBrowserDependencyFactory + virtual content::WebContents* CreateWebContents(bool incognito) OVERRIDE; + virtual AwContentsContainer* CreateContentsContainer( + content::WebContents* contents) OVERRIDE; + virtual content::JavaScriptDialogCreator* GetJavaScriptDialogCreator() + OVERRIDE; + + private: + DISALLOW_COPY_AND_ASSIGN(AwBrowserDependencyFactoryImpl); +}; + +} // namespace android_webview + +#endif // ANDROID_WEBVIEW_LIB_BROWSER_DELEGATE_IMPL_H_ + diff --git a/android_webview/lib/aw_content_browser_client.cc b/android_webview/lib/aw_content_browser_client.cc new file mode 100644 index 0000000..bc34974 --- /dev/null +++ b/android_webview/lib/aw_content_browser_client.cc @@ -0,0 +1,22 @@ +// 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/lib/aw_content_browser_client.h" + +#include "android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.h" + +namespace android_webview { + +AwContentBrowserClient::AwContentBrowserClient() + : ChromeContentBrowserClient() { +} + +AwContentBrowserClient::~AwContentBrowserClient() { +} + +void AwContentBrowserClient::ResourceDispatcherHostCreated() { + AwResourceDispatcherHostDelegate::ResourceDispatcherHostCreated(); +} + +} // namespace android_webview diff --git a/android_webview/lib/aw_content_browser_client.h b/android_webview/lib/aw_content_browser_client.h new file mode 100644 index 0000000..0972032 --- /dev/null +++ b/android_webview/lib/aw_content_browser_client.h @@ -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. + +#ifndef ANDROID_WEBVIEW_LIB_AW_CONTENT_BROWSER_CLIENT_H_ +#define ANDROID_WEBVIEW_LIB_AW_CONTENT_BROWSER_CLIENT_H_ + +#include "chrome/browser/chrome_content_browser_client.h" + +namespace android_webview { + +// TODO(boliu): Remove chrome/ dependency and inherit from +// content::ContentBrowserClient directly. +class AwContentBrowserClient : public chrome::ChromeContentBrowserClient { + public: + AwContentBrowserClient(); + virtual ~AwContentBrowserClient(); + + // Overriden methods from ContentBrowserClient. + virtual void ResourceDispatcherHostCreated() OVERRIDE; +}; + +} // namespace android_webview + +#endif // ANDROID_WEBVIEW_LIB_AW_CONTENT_BROWSER_CLIENT_H_ diff --git a/android_webview/lib/main/webview_main_delegate.cc b/android_webview/lib/main/webview_main_delegate.cc index 9ff742a..3e05463 100644 --- a/android_webview/lib/main/webview_main_delegate.cc +++ b/android_webview/lib/main/webview_main_delegate.cc @@ -4,9 +4,10 @@ #include "android_webview/lib/main/webview_main_delegate.h" +#include "android_webview/lib/aw_browser_dependency_factory_impl.h" +#include "android_webview/lib/aw_content_browser_client.h" #include "base/lazy_instance.h" #include "base/logging.h" -#include "chrome/browser/chrome_content_browser_client.h" #include "chrome/common/chrome_paths.h" #include "chrome/renderer/chrome_content_renderer_client.h" #include "content/public/browser/browser_main_runner.h" @@ -14,7 +15,7 @@ namespace android_webview { -base::LazyInstance<chrome::ChromeContentBrowserClient> +base::LazyInstance<AwContentBrowserClient> g_webview_content_browser_client = LAZY_INSTANCE_INITIALIZER; base::LazyInstance<chrome::ChromeContentRendererClient> g_webview_content_renderer_client = LAZY_INSTANCE_INITIALIZER; @@ -46,6 +47,8 @@ int WebViewMainDelegate::RunProcess( const std::string& process_type, const content::MainFunctionParams& main_function_params) { if (process_type.empty()) { + AwBrowserDependencyFactoryImpl::InstallInstance(); + browser_runner_.reset(content::BrowserMainRunner::Create()); int exit_code = browser_runner_->Initialize(main_function_params); DCHECK(exit_code < 0); diff --git a/android_webview/native/android_web_view_util.cc b/android_webview/native/android_web_view_util.cc new file mode 100644 index 0000000..3b8c830 --- /dev/null +++ b/android_webview/native/android_web_view_util.cc @@ -0,0 +1,20 @@ +// 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_web_view_util.h" + +#include "android_webview/native/aw_browser_dependency_factory.h" +#include "base/android/jni_android.h" +#include "jni/AndroidWebViewUtil_jni.h" + +static jint CreateNativeWebContents( + JNIEnv* env, jclass clazz, jboolean incognito) { + android_webview::AwBrowserDependencyFactory* browser_deps = + android_webview::AwBrowserDependencyFactory::GetInstance(); + return reinterpret_cast<jint>(browser_deps->CreateWebContents(incognito)); +} + +bool RegisterAndroidWebViewUtil(JNIEnv* env) { + return RegisterNativesImpl(env); +} diff --git a/android_webview/native/android_web_view_util.h b/android_webview/native/android_web_view_util.h new file mode 100644 index 0000000..c29f829 --- /dev/null +++ b/android_webview/native/android_web_view_util.h @@ -0,0 +1,13 @@ +// 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_WEB_VIEW_UTIL_H_ +#define ANDROID_WEBVIEW_NATIVE_ANDROID_WEB_VIEW_UTIL_H_ + +#include "base/android/jni_android.h" + +// Register the AndroidWebViewUtil's native methods through JNI. +bool RegisterAndroidWebViewUtil(JNIEnv* env); + +#endif // ANDROID_WEBVIEW_NATIVE_ANDROID_WEB_VIEW_UTIL_H_ diff --git a/android_webview/native/android_webview_jni_registrar.cc b/android_webview/native/android_webview_jni_registrar.cc index eb13e11..cb63594 100644 --- a/android_webview/native/android_webview_jni_registrar.cc +++ b/android_webview/native/android_webview_jni_registrar.cc @@ -4,14 +4,25 @@ #include "android_webview/native/android_webview_jni_registrar.h" +#include "android_webview/native/android_web_view_util.h" +#include "android_webview/native/aw_contents.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 { +static base::android::RegistrationMethod kWebViewRegisteredMethods[] = { + { "AndroidWebViewUtil", RegisterAndroidWebViewUtil }, + { "AwContents", RegisterAwContents }, +}; + bool RegisterJni(JNIEnv* env) { - return web_contents_delegate_android::RegisterJni(env); + if (!web_contents_delegate_android::RegisterJni(env)) + return false; + + return RegisterNativeMethods(env, + kWebViewRegisteredMethods, arraysize(kWebViewRegisteredMethods)); } } // namespace android_webview diff --git a/android_webview/native/aw_browser_dependency_factory.cc b/android_webview/native/aw_browser_dependency_factory.cc new file mode 100644 index 0000000..68b6aa6 --- /dev/null +++ b/android_webview/native/aw_browser_dependency_factory.cc @@ -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. + +#include "android_webview/native/aw_browser_dependency_factory.h" + +#include "base/logging.h" + +namespace android_webview { + +namespace { + +AwBrowserDependencyFactory* g_instance = NULL; + +} // namespace + +AwBrowserDependencyFactory::AwBrowserDependencyFactory() {} + +AwBrowserDependencyFactory::~AwBrowserDependencyFactory() {} + +// static +void AwBrowserDependencyFactory::SetInstance( + AwBrowserDependencyFactory* delegate) { + g_instance = delegate; +} + +// static +AwBrowserDependencyFactory* AwBrowserDependencyFactory::GetInstance() { + DCHECK(g_instance); // Must always be confirgured on startup. + return g_instance; +} + +} // namespace android_webview + diff --git a/android_webview/native/aw_browser_dependency_factory.h b/android_webview/native/aw_browser_dependency_factory.h new file mode 100644 index 0000000..ebf03fd --- /dev/null +++ b/android_webview/native/aw_browser_dependency_factory.h @@ -0,0 +1,60 @@ +// 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_AW_BROWSER_DELEGATE_H_ +#define ANDROID_WEBVIEW_AW_BROWSER_DELEGATE_H_ + +#include "base/basictypes.h" + +namespace content { +class JavaScriptDialogCreator; +class WebContents; +} + +namespace android_webview { + +class AwContentsContainer; + +// The concrete class implementing this interface is the responsible for +// creating he browser component objects that the Android WebView depends on. +// The motivation for this abstraction is to keep code under +// android_webview/native from holding direct chrome/ layer dependencies. +// Note this is a distinct role to the Webview embedder proper: this class is +// about 'static' environmental decoupling, allowing dependency injection by the +// top-level lib, whereas runtime behavior is controlled by propagated back to +// the embedding application code via WebContentsDelegate and the like. +class AwBrowserDependencyFactory { + public: + virtual ~AwBrowserDependencyFactory(); + + // Allows the lib executive to inject the delegate instance. Ownership of + // |delegate| is NOT transferred, but the object must be long-lived. + static void SetInstance(AwBrowserDependencyFactory* delegate); + + // Returns the singleton instance. |SetInstance| must have been called. + static AwBrowserDependencyFactory* GetInstance(); + + // Constructs and returns ownership of a WebContents instance. + virtual content::WebContents* CreateWebContents(bool incognito) = 0; + + // Creates and returns ownership of a new content container instance. That + // instance will take ownership of the passed |contents|. + 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(); + + private: + DISALLOW_COPY_AND_ASSIGN(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 new file mode 100644 index 0000000..ce29d18 --- /dev/null +++ b/android_webview/native/aw_contents.cc @@ -0,0 +1,66 @@ +// 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_contents.h" + +#include "android_webview/native/aw_browser_dependency_factory.h" +#include "android_webview/native/aw_contents_container.h" +#include "android_webview/native/aw_web_contents_delegate.h" +#include "base/android/jni_android.h" +#include "base/android/jni_string.h" +#include "content/public/browser/android/content_view_core.h" +#include "content/public/browser/web_contents.h" +#include "jni/AwContents_jni.h" + +using base::android::AttachCurrentThread; +using base::android::ConvertUTF16ToJavaString; +using content::ContentViewCore; +using content::WebContents; + +namespace android_webview { + +AwContents::AwContents(JNIEnv* env, + jobject obj, + jobject web_contents_delegate, + bool private_browsing) + : java_ref_(env, obj), + web_contents_delegate_( + new AwWebContentsDelegate(env, web_contents_delegate)) { + android_webview::AwBrowserDependencyFactory* dependency_factory = + android_webview::AwBrowserDependencyFactory::GetInstance(); + content::WebContents* web_contents = + dependency_factory->CreateWebContents(private_browsing); + contents_container_.reset(dependency_factory->CreateContentsContainer( + web_contents)); + web_contents->SetDelegate(web_contents_delegate_.get()); + web_contents_delegate_->SetJavaScriptDialogCreator( + dependency_factory->GetJavaScriptDialogCreator()); +} + +AwContents::~AwContents() { +} + +jint AwContents::GetWebContents(JNIEnv* env, jobject obj) { + return reinterpret_cast<jint>(contents_container_->GetWebContents()); +} + +void AwContents::Destroy(JNIEnv* env, jobject obj) { + delete this; +} + +static jint Init(JNIEnv* env, + jobject obj, + jobject web_contents_delegate, + jboolean private_browsing) { + AwContents* tab = new AwContents(env, obj, web_contents_delegate, + private_browsing); + return reinterpret_cast<jint>(tab); +} + +bool RegisterAwContents(JNIEnv* env) { + return RegisterNativesImpl(env) >= 0; +} + + +} // namespace android_webview diff --git a/android_webview/native/aw_contents.h b/android_webview/native/aw_contents.h new file mode 100644 index 0000000..b37511a --- /dev/null +++ b/android_webview/native/aw_contents.h @@ -0,0 +1,51 @@ +// 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_CONTENTS_H_ +#define ANDROID_WEBVIEW_NATIVE_AW_CONTENTS_H_ + +#include <jni.h> + +#include "base/android/jni_helper.h" +#include "base/memory/scoped_ptr.h" + +class TabContents; + +namespace content { +class WebContents; +} + +namespace android_webview { + +class AwContentsContainer; +class AwWebContentsDelegate; + +// Native side of java-class of same name. +// Provides the ownership of and access to browser components required for +// WebView functionality; analogous to chrome's TabContents, but with a +// level of indirection provided by the AwContentsContainer abstraction. +class AwContents { + public: + AwContents(JNIEnv* env, + jobject obj, + jobject web_contents_delegate, + bool private_browsing); + ~AwContents(); + + jint GetWebContents(JNIEnv* env, jobject obj); + void Destroy(JNIEnv* env, jobject obj); + + private: + JavaObjectWeakGlobalRef java_ref_; + scoped_ptr<AwContentsContainer> contents_container_; + scoped_ptr<AwWebContentsDelegate> web_contents_delegate_; + + DISALLOW_COPY_AND_ASSIGN(AwContents); +}; + +bool RegisterAwContents(JNIEnv* env); + +} // namespace android_webview + +#endif // ANDROID_WEBVIEW_NATIVE_AW_CONTENTS_H_ diff --git a/android_webview/native/aw_contents_container.h b/android_webview/native/aw_contents_container.h new file mode 100644 index 0000000..8ab4631 --- /dev/null +++ b/android_webview/native/aw_contents_container.h @@ -0,0 +1,31 @@ +// 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_CONTENTS_CONTAINER_H_ +#define ANDROID_WEBVIEW_NATIVE_AW_CONTENTS_CONTAINER_H_ + +namespace content { +class WebContents; +} + +namespace android_webview { + +// Abstraction that contains and owns the components that we assemble to +// make a working WebView instance. This holds a role analogous to the +// TabContents class in the chrome module, but at a higher level of abstraction. +class AwContentsContainer { + public: + // Destroying the container will tear down the sub-components of this content. + virtual ~AwContentsContainer() {} + + // Ownership remains with this container. + virtual content::WebContents* GetWebContents() = 0; + + protected: + AwContentsContainer() {} +}; + +} // namespace android_webview + +#endif // ANDROID_WEBVIEW_NATIVE_AW_CONTENTS_CONTAINER_H_ diff --git a/android_webview/native/intercepted_request_data.cc b/android_webview/native/intercepted_request_data.cc new file mode 100644 index 0000000..80649bd --- /dev/null +++ b/android_webview/native/intercepted_request_data.cc @@ -0,0 +1,55 @@ +// 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/intercepted_request_data.h" + +#include "base/android/jni_android.h" +#include "base/android/jni_string.h" +#include "jni/InterceptedRequestData_jni.h" + +using std::string; +using base::android::ScopedJavaLocalRef; + +InterceptedRequestData::InterceptedRequestData( + JNIEnv* env, base::android::JavaRef<jobject> obj) { + java_object_.Reset(env, obj.obj()); +} + +InterceptedRequestData::~InterceptedRequestData() { +} + +ScopedJavaLocalRef<jobject> +InterceptedRequestData::GetInputStream(JNIEnv* env) const { + return Java_InterceptedRequestData_getData(env, java_object_.obj()); +} + +bool InterceptedRequestData::GetMimeType(JNIEnv* env, + string* mime_type) const { + ScopedJavaLocalRef<jstring> jstring_mime_type = + Java_InterceptedRequestData_getMimeType(env, java_object_.obj()); + if (jstring_mime_type.is_null()) + return false; + *mime_type = ConvertJavaStringToUTF8(jstring_mime_type); + return true; +} + +bool InterceptedRequestData::GetCharset( + JNIEnv* env, string* charset) const { + ScopedJavaLocalRef<jstring> jstring_charset = + Java_InterceptedRequestData_getCharset(env, java_object_.obj()); + if (jstring_charset.is_null()) + return false; + *charset = ConvertJavaStringToUTF8(jstring_charset); + return true; +} + +bool RegisterInterceptedRequestData(JNIEnv* env) { + if (g_InterceptedRequestData_clazz) + return true; + if (!base::android::HasClass(env, kInterceptedRequestDataClassPath)) { + DLOG(ERROR) << "Unable to find class InterceptedRequestData!"; + return false; + } + return RegisterNativesImpl(env); +} diff --git a/android_webview/native/intercepted_request_data.h b/android_webview/native/intercepted_request_data.h new file mode 100644 index 0000000..e528b3e --- /dev/null +++ b/android_webview/native/intercepted_request_data.h @@ -0,0 +1,31 @@ +// 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_INTERCEPTED_REQUEST_DATA_H_ +#define CONTENT_BROWSER_ANDROID_INTERCEPTED_REQUEST_DATA_H_ + +#include <string> + +#include "base/android/scoped_java_ref.h" +#include "base/memory/ref_counted.h" + +class InterceptedRequestData { + public: + InterceptedRequestData(JNIEnv* env, + base::android::JavaRef<jobject> obj); + ~InterceptedRequestData(); + + base::android::ScopedJavaLocalRef<jobject> GetInputStream(JNIEnv* env) const; + bool GetMimeType(JNIEnv* env, std::string* mime_type) const; + bool GetCharset(JNIEnv* env, std::string* charset) const; + + private: + base::android::ScopedJavaGlobalRef<jobject> java_object_; + + DISALLOW_COPY_AND_ASSIGN(InterceptedRequestData); +}; + +bool RegisterInterceptedRequestData(JNIEnv* env); + +#endif // CONTENT_BROWSER_ANDROID_INTERCEPTED_REQUEST_DATA_H_ diff --git a/android_webview/native/webview_native.gyp b/android_webview/native/webview_native.gyp index 7b31a4a..0cbb379 100644 --- a/android_webview/native/webview_native.gyp +++ b/android_webview/native/webview_native.gyp @@ -22,14 +22,26 @@ 'sources': [ 'android_webview_jni_registrar.cc', 'android_webview_jni_registrar.h', + 'android_web_view_util.cc', + 'android_web_view_util.h', + 'aw_browser_dependency_factory.cc', + 'aw_browser_dependency_factory.h', + 'aw_contents_container.h', + 'aw_contents.cc', + 'aw_contents.h', 'aw_web_contents_delegate.cc', 'aw_web_contents_delegate.h', + 'intercepted_request_data.cc', + 'intercepted_request_data.h', ], }, { 'target_name': 'android_webview_native_jni', 'type': 'none', 'sources': [ + '../java/src/org/chromium/android_webview/AndroidWebViewUtil.java', + '../java/src/org/chromium/android_webview/AwContents.java', + '../java/src/org/chromium/android_webview/InterceptedRequestData.java', ], 'variables': { 'jni_gen_dir': 'android_webview', |