diff options
17 files changed, 372 insertions, 233 deletions
diff --git a/chrome/android/testshell/java/src/org/chromium/chrome/testshell/TabManager.java b/chrome/android/testshell/java/src/org/chromium/chrome/testshell/TabManager.java index 649b40f..b5f64c7 100644 --- a/chrome/android/testshell/java/src/org/chromium/chrome/testshell/TabManager.java +++ b/chrome/android/testshell/java/src/org/chromium/chrome/testshell/TabManager.java @@ -5,9 +5,6 @@ package org.chromium.chrome.testshell; import android.util.AttributeSet; -import android.view.Surface; -import android.view.SurfaceHolder; -import android.view.SurfaceView; import android.view.ViewGroup; import android.content.Context; import android.widget.FrameLayout; @@ -15,14 +12,14 @@ import android.widget.LinearLayout; import org.chromium.base.JNINamespace; -import org.chromium.chrome.browser.ChromeWebContentsDelegateAndroid; import org.chromium.chrome.browser.TabBase; +import org.chromium.content.browser.ContentViewRenderView; import org.chromium.ui.gfx.NativeWindow; /** * The TabManager hooks together all of the related {@link View}s that are used to represent * a {@link TabBase}. It properly builds a {@link TabBase} and makes sure that the {@link Toolbar} - * and {@link SurfaceView} show the proper content. + * and {@link ContentViewRenderView} show the proper content. */ @JNINamespace("chrome") public class TabManager extends LinearLayout { @@ -30,7 +27,7 @@ public class TabManager extends LinearLayout { private NativeWindow mWindow; private ViewGroup mContentViewHolder; - private SurfaceView mRenderTarget; + private ContentViewRenderView mRenderTarget; private TestShellToolbar mToolbar; private TabBase mCurrentTab; @@ -43,7 +40,6 @@ public class TabManager extends LinearLayout { */ public TabManager(Context context, AttributeSet attrs) { super(context, attrs); - nativeInit(this); } @Override @@ -52,25 +48,16 @@ public class TabManager extends LinearLayout { mContentViewHolder = (ViewGroup) findViewById(R.id.content_container); mToolbar = (TestShellToolbar) findViewById(R.id.toolbar); - mRenderTarget = (SurfaceView) findViewById(R.id.render_target); - mRenderTarget.getHolder().addCallback(new SurfaceHolder.Callback() { + mRenderTarget = new ContentViewRenderView(getContext()) { @Override - public void surfaceDestroyed(SurfaceHolder holder) { - nativeSurfaceDestroyed(); - } - - @Override - public void surfaceCreated(SurfaceHolder holder) { - nativeSurfaceCreated(holder.getSurface()); - + protected void onReadyToRender() { if (mCurrentTab == null) createTab(mStartupUrl); } - - @Override - public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { - nativeSurfaceSetSize(width, height); - } - }); + }; + mContentViewHolder.addView(mRenderTarget, + new FrameLayout.LayoutParams( + FrameLayout.LayoutParams.MATCH_PARENT, + FrameLayout.LayoutParams.MATCH_PARENT)); } /** @@ -106,13 +93,14 @@ public class TabManager extends LinearLayout { } private boolean isRenderTargetInitialized() { - return mRenderTarget != null && mRenderTarget.getHolder().getSurface() != null; + return mRenderTarget != null && mRenderTarget.isInitialized(); } private void setCurrentTab(TabBase tab) { + int nativeContentViewLayerRenderer = mRenderTarget.getNativeContentViewLayerRenderer(); if (mCurrentTab != null) { mContentViewHolder.removeView(mCurrentTab.getContentView()); - nativeHideTab(mCurrentTab.getNativeTab()); + nativeHideTab(mCurrentTab.getNativeTab(), nativeContentViewLayerRenderer); mCurrentTab.destroy(); } @@ -121,13 +109,9 @@ public class TabManager extends LinearLayout { mToolbar.showTab(mCurrentTab); mContentViewHolder.addView(mCurrentTab.getContentView()); mCurrentTab.getContentView().requestFocus(); - nativeShowTab(mCurrentTab.getNativeTab()); + nativeShowTab(mCurrentTab.getNativeTab(), nativeContentViewLayerRenderer); } - private static native void nativeShowTab(int jtab); - private static native void nativeHideTab(int jtab); - private static native void nativeInit(Object renderTargetInstance); - private static native void nativeSurfaceCreated(Surface surface); - private static native void nativeSurfaceDestroyed(); - private static native void nativeSurfaceSetSize(int width, int height); + private static native void nativeShowTab(int jtab, int contentViewLayerRenderer); + private static native void nativeHideTab(int jtab, int contentViewLayerRenderer); }
\ No newline at end of file diff --git a/chrome/android/testshell/res/layout/testshell_activity.xml b/chrome/android/testshell/res/layout/testshell_activity.xml index 43323a6..4346e59 100644 --- a/chrome/android/testshell/res/layout/testshell_activity.xml +++ b/chrome/android/testshell/res/layout/testshell_activity.xml @@ -44,9 +44,6 @@ android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1"> - <SurfaceView android:id="@+id/render_target" - android:layout_width="match_parent" - android:layout_height="match_parent" /> </FrameLayout> - + </org.chromium.chrome.testshell.TabManager> diff --git a/chrome/android/testshell/tab_manager.cc b/chrome/android/testshell/tab_manager.cc index fc379dd..0a9da47 100644 --- a/chrome/android/testshell/tab_manager.cc +++ b/chrome/android/testshell/tab_manager.cc @@ -12,52 +12,14 @@ #include "base/lazy_instance.h" #include "base/message_loop.h" #include "chrome/browser/android/tab_base_android_impl.h" -#include "content/public/browser/android/compositor.h" -#include "content/public/browser/android/draw_delegate.h" +#include "content/public/browser/android/content_view_layer_renderer.h" #include "jni/TabManager_jni.h" #include "third_party/WebKit/Source/Platform/chromium/public/WebLayer.h" #include <android/native_window_jni.h> using base::android::ScopedJavaLocalRef; - -namespace { - -class CompositorClient : public content::Compositor::Client { - public: - virtual void ScheduleComposite() OVERRIDE; -}; - -struct GlobalState { - GlobalState() - : g_scheduled_composite(false) {} - CompositorClient client; - scoped_ptr<content::Compositor> compositor; - scoped_ptr<WebKit::WebLayer> root_layer; - bool g_scheduled_composite; -}; - -base::LazyInstance<GlobalState> g_global_state = LAZY_INSTANCE_INITIALIZER; - -content::Compositor* GetCompositor() { - return g_global_state.Get().compositor.get(); -} - -void Composite() { - g_global_state.Get().g_scheduled_composite = false; - if (GetCompositor()) { - GetCompositor()->Composite(); - } -} - -void CompositorClient::ScheduleComposite() { - if (!g_global_state.Get().g_scheduled_composite) { - g_global_state.Get().g_scheduled_composite = true; - MessageLoop::current()->PostTask(FROM_HERE, base::Bind(&Composite)); - } -} - -} // anonymous namespace +using content::ContentViewLayerRenderer; namespace chrome { @@ -66,48 +28,22 @@ bool RegisterTabManager(JNIEnv* env) { return RegisterNativesImpl(env); } -static void Init(JNIEnv* env, jclass clazz, jobject obj) { - if (!GetCompositor()) { - content::Compositor::Initialize(); - g_global_state.Get().compositor.reset(content::Compositor::Create( - &g_global_state.Get().client)); - DCHECK(!g_global_state.Get().root_layer.get()); - g_global_state.Get().root_layer.reset(WebKit::WebLayer::create()); - } -} - -static void SurfaceCreated(JNIEnv* env, jclass clazz, jobject jsurface) { - ANativeWindow* native_window = ANativeWindow_fromSurface(env, jsurface); - if (native_window) { - GetCompositor()->SetWindowSurface(native_window); - ANativeWindow_release(native_window); - GetCompositor()->SetRootLayer(g_global_state.Get().root_layer.get()); - } -} - -static void SurfaceDestroyed(JNIEnv* env, jclass clazz) { - GetCompositor()->SetWindowSurface(NULL); -} - -static void SurfaceSetSize( - JNIEnv* env, jclass clazz, jint width, jint height) { - gfx::Size size = gfx::Size(width, height); - content::DrawDelegate::GetInstance()->SetBounds(size); - GetCompositor()->SetWindowBounds(size); -} - -static void ShowTab(JNIEnv* env, jclass clazz, jint jtab) { - if (!GetCompositor()) - return; +static void ShowTab(JNIEnv* env, jclass clazz, jint jtab, + jint j_content_view_layer_renderer) { TabBaseAndroidImpl* tab = reinterpret_cast<TabBaseAndroidImpl*>(jtab); - g_global_state.Get().root_layer->addChild(tab->tab_layer()); + ContentViewLayerRenderer* content_view_layer_renderer = + reinterpret_cast<ContentViewLayerRenderer*>( + j_content_view_layer_renderer); + content_view_layer_renderer->AttachLayer(tab->tab_layer()); } -static void HideTab(JNIEnv* env, jclass clazz, jint jtab) { - if (!GetCompositor()) - return; +static void HideTab(JNIEnv* env, jclass clazz, jint jtab, + jint j_content_view_layer_renderer) { TabBaseAndroidImpl* tab = reinterpret_cast<TabBaseAndroidImpl*>(jtab); - tab->tab_layer()->removeFromParent(); + ContentViewLayerRenderer* content_view_layer_renderer = + reinterpret_cast<ContentViewLayerRenderer*>( + j_content_view_layer_renderer); + content_view_layer_renderer->DetachLayer(tab->tab_layer()); } } // namespace chrome diff --git a/content/browser/android/browser_jni_registrar.cc b/content/browser/android/browser_jni_registrar.cc index 59274e0..77ef26d 100644 --- a/content/browser/android/browser_jni_registrar.cc +++ b/content/browser/android/browser_jni_registrar.cc @@ -10,6 +10,7 @@ #include "content/browser/android/content_settings.h" #include "content/browser/android/content_video_view.h" #include "content/browser/android/content_view_core_impl.h" +#include "content/browser/android/content_view_render_view.h" #include "content/browser/android/content_view_statics.h" #include "content/browser/android/download_controller_android_impl.h" #include "content/browser/android/load_url_params.h" @@ -31,6 +32,7 @@ base::android::RegistrationMethod kContentRegisteredMethods[] = { { "BrowserProcessSurfaceTexture", SurfaceTexturePeerBrowserImpl::RegisterBrowserProcessSurfaceTexture }, { "ContentSettings", content::ContentSettings::RegisterContentSettings }, + { "ContentViewRenderView", content::RegisterContentViewRenderView }, { "ContentVideoView", content::ContentVideoView::RegisterContentVideoView }, { "ContentViewCore", content::RegisterContentViewCore }, { "DownloadControllerAndroidImpl", diff --git a/content/browser/android/content_view_render_view.cc b/content/browser/android/content_view_render_view.cc new file mode 100644 index 0000000..1db4e61 --- /dev/null +++ b/content/browser/android/content_view_render_view.cc @@ -0,0 +1,141 @@ +// 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_view_render_view.h" + +#include "base/android/jni_android.h" +#include "base/android/jni_string.h" +#include "base/android/scoped_java_ref.h" +#include "base/bind.h" +#include "base/lazy_instance.h" +#include "base/memory/scoped_ptr.h" +#include "base/message_loop.h" +#include "content/public/browser/android/compositor.h" +#include "content/public/browser/android/content_view_layer_renderer.h" +#include "content/public/browser/android/draw_delegate.h" +#include "jni/ContentViewRenderView_jni.h" +#include "third_party/WebKit/Source/Platform/chromium/public/WebLayer.h" +#include "ui/gfx/size.h" + +#include <android/native_window_jni.h> + +using base::android::ScopedJavaLocalRef; +using base::android::ScopedJavaGlobalRef; +using content::Compositor; +using content::DrawDelegate; + +namespace { + +class CompositorClient : public Compositor::Client { + public: + virtual void ScheduleComposite() OVERRIDE; +}; + +class ContentViewLayerRendererImpl; + +struct GlobalState { + GlobalState() : g_scheduled_composite(false) {} + ScopedJavaGlobalRef<jobject> j_obj; + CompositorClient client; + scoped_ptr<content::Compositor> compositor; + scoped_ptr<WebKit::WebLayer> root_layer; + scoped_ptr<ContentViewLayerRendererImpl> layer_renderer; + bool g_scheduled_composite; +}; + +base::LazyInstance<GlobalState> g_global_state = LAZY_INSTANCE_INITIALIZER; + +content::Compositor* GetCompositor() { + return g_global_state.Get().compositor.get(); +} + +class ContentViewLayerRendererImpl : public content::ContentViewLayerRenderer { + public: + ContentViewLayerRendererImpl() {} + virtual ~ContentViewLayerRendererImpl() {} + + private: + virtual void AttachLayer(WebKit::WebLayer* layer) OVERRIDE { + if (GetCompositor()) + g_global_state.Get().root_layer->addChild(layer); + } + + virtual void DetachLayer(WebKit::WebLayer* layer) OVERRIDE { + if (GetCompositor()) + layer->removeFromParent(); + } + + DISALLOW_COPY_AND_ASSIGN(ContentViewLayerRendererImpl); +}; + +void Composite() { + g_global_state.Get().g_scheduled_composite = false; + if (GetCompositor()) + GetCompositor()->Composite(); +} + +void CompositorClient::ScheduleComposite() { + if (!g_global_state.Get().g_scheduled_composite) { + g_global_state.Get().g_scheduled_composite = true; + MessageLoop::current()->PostTask(FROM_HERE, base::Bind(&Composite)); + } +} + +void InitCompositor() { + if (GetCompositor()) + return; + + Compositor::Initialize(); + g_global_state.Get().compositor.reset( + Compositor::Create(&g_global_state.Get().client)); + DCHECK(!g_global_state.Get().root_layer.get()); + g_global_state.Get().root_layer.reset(WebKit::WebLayer::create()); + g_global_state.Get().layer_renderer.reset(new ContentViewLayerRendererImpl()); +} + +} // anonymous namespace + +namespace content { + +// Register native methods +bool RegisterContentViewRenderView(JNIEnv* env) { + return RegisterNativesImpl(env); +} + +static void Init(JNIEnv* env, jobject obj) { + g_global_state.Get().j_obj.Reset(ScopedJavaLocalRef<jobject>(env, obj)); +} + +static jint GetNativeContentViewLayerRenderer(JNIEnv* env, jclass clazz) { + // The compositor might not have been initialized yet. + InitCompositor(); + // Note it's important to static cast to the interface here as we'll + // reinterpret cast the jint back to the interace later on. + return reinterpret_cast<jint>(static_cast<content::ContentViewLayerRenderer*>( + g_global_state.Get().layer_renderer.get())); +} + +static void SurfaceCreated( + JNIEnv* env, jclass clazz, jobject jsurface) { + InitCompositor(); + ANativeWindow* native_window = ANativeWindow_fromSurface(env, jsurface); + if (native_window) { + GetCompositor()->SetWindowSurface(native_window); + ANativeWindow_release(native_window); + GetCompositor()->SetRootLayer(g_global_state.Get().root_layer.get()); + } +} + +static void SurfaceDestroyed(JNIEnv* env, jclass clazz) { + GetCompositor()->SetWindowSurface(NULL); +} + +static void SurfaceSetSize( + JNIEnv* env, jclass clazz, jint width, jint height) { + gfx::Size size = gfx::Size(width, height); + DrawDelegate::GetInstance()->SetBounds(size); + GetCompositor()->SetWindowBounds(size); +} + +} // namespace content diff --git a/content/browser/android/content_view_render_view.h b/content/browser/android/content_view_render_view.h new file mode 100644 index 0000000..2770a5e --- /dev/null +++ b/content/browser/android/content_view_render_view.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 CONTENT_BROWSER_ANDROID_CONTENT_VIEW_RENDER_VIEW_H_ +#define CONTENT_BROWSER_ANDROID_CONTENT_VIEW_RENDER_VIEW_H_ + +#include <jni.h> + +namespace content { + +// Registers the JNI methods for ContentViewRender. +bool RegisterContentViewRenderView(JNIEnv* env); + +} + +#endif // CONTENT_BROWSER_ANDROID_CONTENT_VIEW_RENDER_VIEW_H_ diff --git a/content/content_browser.gypi b/content/content_browser.gypi index a86091b..dacdc34 100644 --- a/content/content_browser.gypi +++ b/content/content_browser.gypi @@ -36,6 +36,7 @@ 'public/browser/access_token_store.h', 'public/browser/android/compositor.h', 'public/browser/android/content_view_core.h', + 'public/browser/android/content_view_layer_renderer.h', 'public/browser/android/devtools_auth.h', 'public/browser/android/download_controller_android.h', 'public/browser/android/draw_delegate.h', @@ -215,6 +216,8 @@ 'browser/android/content_video_view.h', 'browser/android/content_view_core_impl.cc', 'browser/android/content_view_core_impl.h', + 'browser/android/content_view_render_view.cc', + 'browser/android/content_view_render_view.h', 'browser/android/content_view_statics.cc', 'browser/android/content_view_statics.h', 'browser/android/cookie_getter_impl.cc', diff --git a/content/content_jni.gypi b/content/content_jni.gypi index 951efa8..6ec0314 100644 --- a/content/content_jni.gypi +++ b/content/content_jni.gypi @@ -16,6 +16,7 @@ 'public/android/java/src/org/chromium/content/browser/ContentSettings.java', 'public/android/java/src/org/chromium/content/browser/ContentVideoView.java', 'public/android/java/src/org/chromium/content/browser/ContentViewCore.java', + 'public/android/java/src/org/chromium/content/browser/ContentViewRenderView.java', 'public/android/java/src/org/chromium/content/browser/ContentViewStatics.java', 'public/android/java/src/org/chromium/content/browser/DeviceOrientation.java', 'public/android/java/src/org/chromium/content/browser/DownloadController.java', diff --git a/content/public/android/java/src/org/chromium/content/browser/ContentViewRenderView.java b/content/public/android/java/src/org/chromium/content/browser/ContentViewRenderView.java new file mode 100644 index 0000000..719ca57 --- /dev/null +++ b/content/public/android/java/src/org/chromium/content/browser/ContentViewRenderView.java @@ -0,0 +1,89 @@ +// 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 android.content.Context; +import android.view.Surface; +import android.view.SurfaceView; +import android.view.SurfaceHolder; +import android.widget.FrameLayout; + +import org.chromium.base.JNINamespace; + +/*** + * This view is used by a ContentView to render its content. + * It renders the layers added to it through the native ContentViewLayerRenderer to its SurfaceView. + * TODO(jcivelli): the API is confusing and complicated. There should be a way to do all that + * wihtout native code. + */ +@JNINamespace("content") +public class ContentViewRenderView extends FrameLayout { + + private SurfaceView mSurfaceView; + + /** + * Constructs a new ContentViewRenderView that should be can to a view hierarchy. + * Native code should add/remove the layers to be rendered through the ContentViewLayerRenderer. + * @param context The context used to create this. + */ + public ContentViewRenderView(Context context) { + super(context); + + nativeInit(); + + mSurfaceView = new SurfaceView(getContext()); + mSurfaceView.getHolder().addCallback(new SurfaceHolder.Callback() { + @Override + public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { + nativeSurfaceSetSize(width, height); + } + + @Override + public void surfaceCreated(SurfaceHolder holder) { + nativeSurfaceCreated(holder.getSurface()); + onReadyToRender(); + } + + @Override + public void surfaceDestroyed(SurfaceHolder holder) { + nativeSurfaceDestroyed(); + } + }); + + addView(mSurfaceView, + new FrameLayout.LayoutParams( + FrameLayout.LayoutParams.MATCH_PARENT, + FrameLayout.LayoutParams.MATCH_PARENT)); + } + + /** + * @return pointer to a native ContentViewLayerRenderer on which the layers to be added should + * be added removed. + */ + public int getNativeContentViewLayerRenderer() { + return nativeGetNativeContentViewLayerRenderer(); + } + + /** + * This method should be subclassed to provide actions to be performed once the view is ready to + * render. + */ + protected void onReadyToRender() { + } + + /** + * @return whether the surface view is initialized and ready to render. + */ + public boolean isInitialized() { + return mSurfaceView.getHolder().getSurface() != null; + } + + private native void nativeInit(); + private static native int nativeGetNativeContentViewLayerRenderer(); + private static native void nativeSurfaceCreated(Surface surface); + private static native void nativeSurfaceDestroyed(); + private static native void nativeSurfaceSetSize(int width, int height); +} + diff --git a/content/public/browser/android/content_view_layer_renderer.h b/content/public/browser/android/content_view_layer_renderer.h new file mode 100644 index 0000000..abc39cc --- /dev/null +++ b/content/public/browser/android/content_view_layer_renderer.h @@ -0,0 +1,28 @@ +// 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_PUBLIC_BROWSER_ANDROID_CONTENT_VIEW_LAYER_RENDERER_H +#define CONTENT_PUBLIC_BROWSER_ANDROID_CONTENT_VIEW_LAYER_RENDERER_H + +// This interface is used by consumers of the ContentViewRenderView to +// attach/detach layers. + +namespace WebKit { +class WebLayer; +} + +namespace content { + +class ContentViewLayerRenderer { + public: + virtual void AttachLayer(WebKit::WebLayer* layer) = 0; + virtual void DetachLayer(WebKit::WebLayer* layer) = 0; + + protected: + virtual ~ContentViewLayerRenderer() {} +}; + +} // namespace content + +#endif // CONTENT_PUBLIC_BROWSER_ANDROID_CONTENT_VIEW_LAYER_RENDERER_H diff --git a/content/shell/android/java/src/org/chromium/content_shell/Shell.java b/content/shell/android/java/src/org/chromium/content_shell/Shell.java index 708df1c..1eeecbfc 100644 --- a/content/shell/android/java/src/org/chromium/content_shell/Shell.java +++ b/content/shell/android/java/src/org/chromium/content_shell/Shell.java @@ -48,7 +48,7 @@ public class Shell extends LinearLayout { private ClipDrawable mProgressDrawable; - private View mSurfaceView; + private View mContentViewRenderView; private NativeWindow mWindow; private boolean mLoading = false; @@ -63,17 +63,19 @@ public class Shell extends LinearLayout { /** * Set the SurfaceView being renderered to as soon as it is available. */ - public void setSurfaceView(View surfaceView) { + public void setContentViewRenderView(View contentViewRenderView) { FrameLayout contentViewHolder = (FrameLayout) findViewById(R.id.contentview_holder); - if (surfaceView == null) { - if (mSurfaceView != null) contentViewHolder.removeView(mSurfaceView); + if (contentViewRenderView == null) { + if (mContentViewRenderView != null) { + contentViewHolder.removeView(mContentViewRenderView); + } } else { - contentViewHolder.addView(surfaceView, + contentViewHolder.addView(contentViewRenderView, new FrameLayout.LayoutParams( FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT)); } - mSurfaceView = surfaceView; + mContentViewRenderView = contentViewRenderView; } /** diff --git a/content/shell/android/java/src/org/chromium/content_shell/ShellManager.java b/content/shell/android/java/src/org/chromium/content_shell/ShellManager.java index 11252ca..9cfc2ea 100644 --- a/content/shell/android/java/src/org/chromium/content_shell/ShellManager.java +++ b/content/shell/android/java/src/org/chromium/content_shell/ShellManager.java @@ -7,13 +7,11 @@ package org.chromium.content_shell; import android.content.Context; import android.util.AttributeSet; import android.view.LayoutInflater; -import android.view.Surface; -import android.view.SurfaceView; -import android.view.SurfaceHolder; import android.widget.FrameLayout; import org.chromium.base.CalledByNative; import org.chromium.base.JNINamespace; +import org.chromium.content.browser.ContentViewRenderView; import org.chromium.ui.gfx.NativeWindow; /** @@ -28,7 +26,7 @@ public class ShellManager extends FrameLayout { private String mStartupUrl = ContentShellActivity.DEFAULT_SHELL_URL; // The target for all content rendering. - private SurfaceView mSurfaceView; + private ContentViewRenderView mContentViewRenderView; /** * Constructor for inflating via XML. @@ -36,25 +34,12 @@ public class ShellManager extends FrameLayout { public ShellManager(Context context, AttributeSet attrs) { super(context, attrs); nativeInit(this); - - mSurfaceView = new SurfaceView(context); - mSurfaceView.getHolder().addCallback(new SurfaceHolder.Callback() { - @Override - public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { - nativeSurfaceSetSize(width, height); - } - + mContentViewRenderView = new ContentViewRenderView(context) { @Override - public void surfaceCreated(SurfaceHolder holder) { - nativeSurfaceCreated(holder.getSurface()); + protected void onReadyToRender() { mActiveShell.loadUrl(mStartupUrl); } - - @Override - public void surfaceDestroyed(SurfaceHolder holder) { - nativeSurfaceDestroyed(); - } - }); + }; } /** @@ -95,6 +80,12 @@ public class ShellManager extends FrameLayout { @SuppressWarnings("unused") @CalledByNative + private int getContentViewLayerRenderer() { + return mContentViewRenderView.getNativeContentViewLayerRenderer(); + } + + @SuppressWarnings("unused") + @CalledByNative private Object createShell() { LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); @@ -106,10 +97,10 @@ public class ShellManager extends FrameLayout { if (mActiveShell.getContentView() != null) { mActiveShell.getContentView().onHide(); } - mActiveShell.setSurfaceView(null); + mActiveShell.setContentViewRenderView(null); } - shellView.setSurfaceView(mSurfaceView); + shellView.setContentViewRenderView(mContentViewRenderView); addView(shellView, new FrameLayout.LayoutParams( FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT)); mActiveShell = shellView; @@ -120,7 +111,4 @@ public class ShellManager extends FrameLayout { private static native void nativeInit(Object shellManagerInstance); private static native void nativeLaunchShell(String url); - private static native void nativeSurfaceCreated(Surface surface); - private static native void nativeSurfaceDestroyed(); - private static native void nativeSurfaceSetSize(int width, int height); } diff --git a/content/shell/android/shell_manager.cc b/content/shell/android/shell_manager.cc index 71ed3ab..79f7803d 100644 --- a/content/shell/android/shell_manager.cc +++ b/content/shell/android/shell_manager.cc @@ -9,78 +9,39 @@ #include "base/android/scoped_java_ref.h" #include "base/bind.h" #include "base/lazy_instance.h" -#include "base/memory/scoped_ptr.h" -#include "base/message_loop.h" #include "content/shell/shell.h" #include "content/shell/shell_browser_context.h" #include "content/shell/shell_content_browser_client.h" -#include "content/public/browser/android/compositor.h" -#include "content/public/browser/android/draw_delegate.h" #include "content/public/browser/web_contents.h" #include "content/shell/shell.h" #include "googleurl/src/gurl.h" #include "jni/ShellManager_jni.h" -#include "third_party/WebKit/Source/Platform/chromium/public/WebLayer.h" -#include "ui/gfx/size.h" - -#include <android/native_window_jni.h> using base::android::ScopedJavaLocalRef; -using content::Compositor; -using content::DrawDelegate; namespace { -class CompositorClient : public Compositor::Client { - public: - virtual void ScheduleComposite() OVERRIDE; -}; - struct GlobalState { - GlobalState() - : g_scheduled_composite(false) {} - base::android::ScopedJavaGlobalRef<jobject> j_obj; - CompositorClient client; - scoped_ptr<content::Compositor> compositor; - scoped_ptr<WebKit::WebLayer> root_layer; - bool g_scheduled_composite; + GlobalState() {} + base::android::ScopedJavaGlobalRef<jobject> j_shell_manager; }; base::LazyInstance<GlobalState> g_global_state = LAZY_INSTANCE_INITIALIZER; -content::Compositor* GetCompositor() { - return g_global_state.Get().compositor.get(); -} - -void Composite() { - g_global_state.Get().g_scheduled_composite = false; - if (GetCompositor()) { - GetCompositor()->Composite(); - } -} - -void CompositorClient::ScheduleComposite() { - if (!g_global_state.Get().g_scheduled_composite) { - g_global_state.Get().g_scheduled_composite = true; - MessageLoop::current()->PostTask(FROM_HERE, base::Bind(&Composite)); - } -} - -} // anonymous namespace +} // namespace namespace content { -jobject CreateShellView() { +jobject CreateShellView(Shell* shell) { JNIEnv* env = base::android::AttachCurrentThread(); - if (!GetCompositor()) { - Compositor::Initialize(); - g_global_state.Get().compositor.reset(Compositor::Create( - &g_global_state.Get().client)); - DCHECK(!g_global_state.Get().root_layer.get()); - g_global_state.Get().root_layer.reset(WebKit::WebLayer::create()); - } - return Java_ShellManager_createShell( - env, g_global_state.Get().j_obj.obj()).Release(); + jobject j_shell_manager = g_global_state.Get().j_shell_manager.obj(); + + ContentViewLayerRenderer* content_view_layer_renderer = + reinterpret_cast<ContentViewLayerRenderer*>( + Java_ShellManager_getContentViewLayerRenderer(env, j_shell_manager)); + shell->SetContentViewLayerRenderer(content_view_layer_renderer); + + return Java_ShellManager_createShell(env, j_shell_manager).Release(); } // Register native methods @@ -89,31 +50,10 @@ bool RegisterShellManager(JNIEnv* env) { } static void Init(JNIEnv* env, jclass clazz, jobject obj) { - g_global_state.Get().j_obj.Reset( + g_global_state.Get().j_shell_manager.Reset( base::android::ScopedJavaLocalRef<jobject>(env, obj)); } -static void SurfaceCreated( - JNIEnv* env, jclass clazz, jobject jsurface) { - ANativeWindow* native_window = ANativeWindow_fromSurface(env, jsurface); - if (native_window) { - GetCompositor()->SetWindowSurface(native_window); - ANativeWindow_release(native_window); - GetCompositor()->SetRootLayer(g_global_state.Get().root_layer.get()); - } -} - -static void SurfaceDestroyed(JNIEnv* env, jclass clazz) { - GetCompositor()->SetWindowSurface(NULL); -} - -static void SurfaceSetSize( - JNIEnv* env, jclass clazz, jint width, jint height) { - gfx::Size size = gfx::Size(width, height); - DrawDelegate::GetInstance()->SetBounds(size); - GetCompositor()->SetWindowBounds(size); -} - void LaunchShell(JNIEnv* env, jclass clazz, jstring jurl) { ShellBrowserContext* browserContext = static_cast<ShellContentBrowserClient*>( @@ -126,13 +66,4 @@ void LaunchShell(JNIEnv* env, jclass clazz, jstring jurl) { NULL); } -void ShellAttachLayer(WebKit::WebLayer* layer) { - g_global_state.Get().root_layer->addChild(layer); -} - - -void ShellRemoveLayer(WebKit::WebLayer* layer) { - layer->removeFromParent(); -} - } // namespace content diff --git a/content/shell/android/shell_manager.h b/content/shell/android/shell_manager.h index 7dcbc34..c79b20f 100644 --- a/content/shell/android/shell_manager.h +++ b/content/shell/android/shell_manager.h @@ -10,6 +10,8 @@ #include "base/android/jni_android.h" #include "base/android/scoped_java_ref.h" +class Shell; + namespace WebKit { class WebLayer; } @@ -20,7 +22,7 @@ namespace content { // window. This view holds the controls and content views necessary to // render a shell window. Returns the java object representing the shell view. // object. -jobject CreateShellView(); +jobject CreateShellView(Shell* shell); // Registers the ShellManager native methods. bool RegisterShellManager(JNIEnv* env); diff --git a/content/shell/shell.cc b/content/shell/shell.cc index 9d9721e..eaac653 100644 --- a/content/shell/shell.cc +++ b/content/shell/shell.cc @@ -45,6 +45,8 @@ Shell::Shell(WebContents* web_contents) url_edit_view_(NULL) #if defined(OS_WIN) && !defined(USE_AURA) , default_edit_wnd_proc_(0) +#elif defined(OS_ANDROID) + , content_view_layer_renderer_(NULL) #endif { registrar_.Add(this, NOTIFICATION_WEB_CONTENTS_TITLE_UPDATED, diff --git a/content/shell/shell.h b/content/shell/shell.h index e8d504c..bc43553 100644 --- a/content/shell/shell.h +++ b/content/shell/shell.h @@ -25,6 +25,9 @@ typedef struct _GtkToolItem GtkToolItem; #elif defined(OS_ANDROID) #include "base/android/scoped_java_ref.h" +namespace content { +class ContentViewLayerRenderer; +} #elif defined(USE_AURA) namespace views { class Widget; @@ -95,6 +98,11 @@ class Shell : public WebContentsDelegate, #elif defined(OS_ANDROID) // Registers the Android Java to native methods. static bool Register(JNIEnv* env); + // Called by the ShellManager to specify the object that should be notified of + // layer changes. + // Note that |content_view_layer_renderer| is owned by the ShellManager. + void SetContentViewLayerRenderer( + ContentViewLayerRenderer* content_view_layer_renderer); #endif // WebContentsDelegate @@ -220,6 +228,9 @@ class Shell : public WebContentsDelegate, int content_height_; #elif defined(OS_ANDROID) base::android::ScopedJavaGlobalRef<jobject> java_object_; + // The ContentViewLayerRenderer that should be notified of compositing layer + // changes. Global so guaranteed to outlive shell. + ContentViewLayerRenderer* content_view_layer_renderer_; #elif defined(USE_AURA) static aura::client::StackingClient* stacking_client_; static views::ViewsDelegate* views_delegate_; diff --git a/content/shell/shell_android.cc b/content/shell/shell_android.cc index ddd1722..08e6bb0 100644 --- a/content/shell/shell_android.cc +++ b/content/shell/shell_android.cc @@ -11,6 +11,7 @@ #include "base/command_line.h" #include "base/logging.h" #include "base/string_piece.h" +#include "content/public/browser/android/content_view_layer_renderer.h" #include "content/public/common/content_switches.h" #include "content/shell/android/shell_manager.h" #include "jni/Shell_jni.h" @@ -34,8 +35,7 @@ void Shell::PlatformEnableUIControl(UIControl control, bool is_enabled) { void Shell::PlatformSetAddressBarURL(const GURL& url) { JNIEnv* env = AttachCurrentThread(); - ScopedJavaLocalRef<jstring> j_url = - ConvertUTF8ToJavaString(env, url.spec()); + ScopedJavaLocalRef<jstring> j_url = ConvertUTF8ToJavaString(env, url.spec()); Java_Shell_onUpdateUrl(env, java_object_.obj(), j_url.obj()); } @@ -45,7 +45,7 @@ void Shell::PlatformSetIsLoading(bool loading) { } void Shell::PlatformCreateWindow(int width, int height) { - java_object_.Reset(AttachCurrentThread(), CreateShellView()); + java_object_.Reset(AttachCurrentThread(), CreateShellView(this)); } void Shell::PlatformSetContents() { @@ -73,11 +73,16 @@ void Shell::Close() { } void Shell::AttachLayer(WebContents* web_contents, WebKit::WebLayer* layer) { - ShellAttachLayer(layer); + content_view_layer_renderer_->AttachLayer(layer); } void Shell::RemoveLayer(WebContents* web_contents, WebKit::WebLayer* layer) { - ShellRemoveLayer(layer); + content_view_layer_renderer_->DetachLayer(layer); +} + +void Shell::SetContentViewLayerRenderer( + ContentViewLayerRenderer* content_view_layer_renderer) { + content_view_layer_renderer_ = content_view_layer_renderer; } // static |