Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(966)

Unified Diff: content/public/android/java/src/org/chromium/content/browser/ContentView.java

Issue 10693134: Revert 146000 - Split out ContentViewCore from ContentView for embedders. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/public/android/java/src/org/chromium/content/browser/ContentView.java
===================================================================
--- content/public/android/java/src/org/chromium/content/browser/ContentView.java (revision 146004)
+++ content/public/android/java/src/org/chromium/content/browser/ContentView.java (working copy)
@@ -5,24 +5,20 @@
package org.chromium.content.browser;
import android.content.Context;
-import android.content.res.Configuration;
-import android.graphics.Canvas;
import android.util.AttributeSet;
-import android.view.KeyEvent;
-import android.view.MotionEvent;
+import android.util.Log;
import android.view.View;
import android.webkit.DownloadListener;
import android.widget.FrameLayout;
-/**
- * The containing view for {@link ContentViewCore} that exists in the Android UI hierarchy and
- * exposes the various {@link View} functionality to it.
- *
- * TODO(joth): Remove any methods overrides from this class that were added for WebView
- * compatibility.
- */
-public class ContentView extends FrameLayout implements ContentViewCore.InternalAccessDelegate {
+import org.chromium.base.JNINamespace;
+import org.chromium.base.WeakContext;
+import org.chromium.content.app.AppResource;
+import org.chromium.content.common.TraceEvent;
+@JNINamespace("content")
+public class ContentView extends FrameLayout {
+
// The following constants match the ones in chrome/common/page_transition_types.h.
// Add more if you need them.
public static final int PAGE_TRANSITION_LINK = 0;
@@ -30,20 +26,14 @@
public static final int PAGE_TRANSITION_AUTO_BOOKMARK = 2;
public static final int PAGE_TRANSITION_START_PAGE = 6;
- /** Translate the find selection into a normal selection. */
- public static final int FIND_SELECTION_ACTION_KEEP_SELECTION =
- ContentViewCore.FIND_SELECTION_ACTION_KEEP_SELECTION;
- /** Clear the find selection. */
- public static final int FIND_SELECTION_ACTION_CLEAR_SELECTION =
- ContentViewCore.FIND_SELECTION_ACTION_CLEAR_SELECTION;
- /** Focus and click the selected node (for links). */
- public static final int FIND_SELECTION_ACTION_ACTIVATE_SELECTION =
- ContentViewCore.FIND_SELECTION_ACTION_ACTIVATE_SELECTION;
+ private static final String TAG = "ContentView";
+ // Personality of the ContentView.
+ private int mPersonality;
// Used when ContentView implements a standalone View.
- public static final int PERSONALITY_VIEW = ContentViewCore.PERSONALITY_VIEW;
+ public static final int PERSONALITY_VIEW = 0;
// Used for Chrome.
- public static final int PERSONALITY_CHROME = ContentViewCore.PERSONALITY_CHROME;
+ public static final int PERSONALITY_CHROME = 1;
/**
* Automatically decide the number of renderer processes to use based on device memory class.
@@ -54,11 +44,41 @@
*/
public static final int MAX_RENDERERS_SINGLE_PROCESS =
AndroidBrowserProcess.MAX_RENDERERS_SINGLE_PROCESS;
- /**
- * Cap on the maximum number of renderer processes that can be requested.
- */
- public static final int MAX_RENDERERS_LIMIT = AndroidBrowserProcess.MAX_RENDERERS_LIMIT;
+ // Used to avoid enabling zooming in / out in WebView zoom controls
+ // if resulting zooming will produce little visible difference.
+ private static float WEBVIEW_ZOOM_CONTROLS_EPSILON = 0.007f;
+
+ // content_view_client.cc depends on ContentView.java holding a ref to the current client
+ // instance since the native side only holds a weak pointer to the client. We chose this
+ // solution over the managed object owning the C++ object's memory since it's a lot simpler
+ // in terms of clean up.
+ private ContentViewClient mContentViewClient;
+
+ private ContentSettings mContentSettings;
+
+ // Native pointer to C++ ContentView object which will be set by nativeInit()
+ private int mNativeContentView = 0;
+
+ private ZoomManager mZoomManager;
+
+ // Cached page scale factor from native
+ private float mNativePageScaleFactor = 1.0f;
+ private float mNativeMinimumScale = 1.0f;
+ private float mNativeMaximumScale = 1.0f;
+
+ // TODO(klobag): this is to avoid a bug in GestureDetector. With multi-touch,
+ // mAlwaysInTapRegion is not reset. So when the last finger is up, onSingleTapUp()
+ // will be mistakenly fired.
+ private boolean mIgnoreSingleTap;
+
+ // The legacy webview DownloadListener.
+ private DownloadListener mDownloadListener;
+ // ContentViewDownloadDelegate adds support for authenticated downloads
+ // and POST downloads. Embedders should prefer ContentViewDownloadDelegate
+ // over DownloadListener.
+ private ContentViewDownloadDelegate mDownloadDelegate;
+
/**
* Enable multi-process ContentView. This should be called by the application before
* constructing any ContentView instances. If enabled, ContentView will run renderers in
@@ -75,66 +95,69 @@
* maximum number of allowed renderers is capped by MAX_RENDERERS_LIMIT.
*/
public static void enableMultiProcess(Context context, int maxRendererProcesses) {
- ContentViewCore.enableMultiProcess(context, maxRendererProcesses);
+ AndroidBrowserProcess.initContentViewProcess(context, maxRendererProcesses);
}
- /**
- * Initialize the process as the platform browser. This must be called before accessing
- * ContentView in order to treat this as a Chromium browser process.
- *
- * @param context Context used to obtain the application context.
- * @param maxRendererProcesses Same as ContentView.enableMultiProcess()
- * @hide Only used by the platform browser.
- */
- public static void initChromiumBrowserProcess(Context context, int maxRendererProcesses) {
- ContentViewCore.initChromiumBrowserProcess(context, maxRendererProcesses);
- }
-
- private ContentViewCore mContentViewCore;
-
public ContentView(Context context, int nativeWebContents, int personality) {
this(context, nativeWebContents, null, android.R.attr.webViewStyle, personality);
}
- public ContentView(Context context, int nativeWebContents, AttributeSet attrs) {
- // TODO(klobag): use the WebViewStyle as the default style for now. It enables scrollbar.
- // When ContentView is moved to framework, we can define its own style in the res.
- this(context, nativeWebContents, attrs, android.R.attr.webViewStyle);
- }
-
- public ContentView(Context context, int nativeWebContents, AttributeSet attrs, int defStyle) {
- this(context, nativeWebContents, attrs, defStyle, PERSONALITY_VIEW);
- }
-
private ContentView(Context context, int nativeWebContents, AttributeSet attrs, int defStyle,
int personality) {
super(context, attrs, defStyle);
- mContentViewCore = new ContentViewCore(context, this, this, nativeWebContents, personality);
+ WeakContext.initializeWeakContext(context);
+ // By default, ContentView will initialize single process mode. The call to
+ // initContentViewProcess below is ignored if either the ContentView host called
+ // enableMultiProcess() or the platform browser called initChromiumBrowserProcess().
+ AndroidBrowserProcess.initContentViewProcess(context, MAX_RENDERERS_SINGLE_PROCESS);
+
+ initialize(context, nativeWebContents, personality);
}
- /**
- * @return The core component of the ContentView that handles JNI communication. Should only be
- * used for passing to native.
- */
- public ContentViewCore getContentViewCore() {
- return mContentViewCore;
+ // TODO(jrg): incomplete; upstream the rest of this method.
+ private void initialize(Context context, int nativeWebContents, int personality) {
+ mNativeContentView = nativeInit(nativeWebContents);
+
+ mPersonality = personality;
+ mContentSettings = new ContentSettings(this, mNativeContentView);
+
+ initGestureDetectors(context);
+
+ Log.i(TAG, "mNativeContentView=0x"+ Integer.toHexString(mNativeContentView));
}
/**
* @return Whether the configured personality of this ContentView is {@link #PERSONALITY_VIEW}.
*/
boolean isPersonalityView() {
- return mContentViewCore.isPersonalityView();
+ switch (mPersonality) {
+ case PERSONALITY_VIEW:
+ return true;
+ case PERSONALITY_CHROME:
+ return false;
+ default:
+ Log.e(TAG, "Unknown ContentView personality: " + mPersonality);
+ return false;
+ }
}
+
/**
* Destroy the internal state of the WebView. This method may only be called
* after the WebView has been removed from the view system. No other methods
* may be called on this WebView after this method has been called.
*/
+ // TODO(jrg): incomplete; upstream the rest of this method.
public void destroy() {
- mContentViewCore.destroy();
+ if (mNativeContentView != 0) {
+ nativeDestroy(mNativeContentView);
+ mNativeContentView = 0;
+ }
+ if (mContentSettings != null) {
+ mContentSettings.destroy();
+ mContentSettings = null;
+ }
}
/**
@@ -142,24 +165,30 @@
* It is illegal to call any other public method after destroy().
*/
public boolean isAlive() {
- return mContentViewCore.isAlive();
+ return mNativeContentView != 0;
}
- /**
- * For internal use. Throws IllegalStateException if mNativeContentView is 0.
- * Use this to ensure we get a useful Java stack trace, rather than a native
- * crash dump, from use-after-destroy bugs in Java code.
- */
- void checkIsAlive() throws IllegalStateException {
- mContentViewCore.checkIsAlive();
- }
-
public void setContentViewClient(ContentViewClient client) {
- mContentViewCore.setContentViewClient(client);
+ if (client == null) {
+ throw new IllegalArgumentException("The client can't be null.");
+ }
+ mContentViewClient = client;
+ if (mNativeContentView != 0) {
+ nativeSetClient(mNativeContentView, mContentViewClient);
+ }
}
ContentViewClient getContentViewClient() {
- return mContentViewCore.getContentViewClient();
+ if (mContentViewClient == null) {
+ // We use the Null Object pattern to avoid having to perform a null check in this class.
+ // We create it lazily because most of the time a client will be set almost immediately
+ // after ContentView is created.
+ mContentViewClient = new ContentViewClient();
+ // We don't set the native ContentViewClient pointer here on purpose. The native
+ // implementation doesn't mind a null delegate and using one is better than passing a
+ // Null Object, since we cut down on the number of JNI calls.
+ }
+ return mContentViewClient;
}
/**
@@ -184,18 +213,33 @@
* omnibox can report suggestions correctly.
*/
public void loadUrlWithoutUrlSanitization(String url, int pageTransition) {
- mContentViewCore.loadUrlWithoutUrlSanitization(url, pageTransition);
+ if (mNativeContentView != 0) {
+ if (isPersonalityView()) {
+ nativeLoadUrlWithoutUrlSanitizationWithUserAgentOverride(
+ mNativeContentView,
+ url,
+ pageTransition,
+ mContentSettings.getUserAgentString());
+ } else {
+ // Chrome stores overridden UA strings in navigation history
+ // items, so they stay the same on going back / forward.
+ nativeLoadUrlWithoutUrlSanitization(
+ mNativeContentView,
+ url,
+ pageTransition);
+ }
+ }
}
void setAllUserAgentOverridesInHistory() {
- mContentViewCore.setAllUserAgentOverridesInHistory();
+ // TODO(tedchoc): Pass user agent override down to native.
}
/**
* Stops loading the current web contents.
*/
public void stopLoading() {
- mContentViewCore.stopLoading();
+ if (mNativeContentView != 0) nativeStopLoading(mNativeContentView);
}
/**
@@ -204,7 +248,8 @@
* @return The URL of the current page.
*/
public String getUrl() {
- return mContentViewCore.getUrl();
+ if (mNativeContentView != 0) return nativeGetURL(mNativeContentView);
+ return null;
}
/**
@@ -213,28 +258,32 @@
* @return The title of the current page.
*/
public String getTitle() {
- return mContentViewCore.getTitle();
+ if (mNativeContentView != 0) return nativeGetTitle(mNativeContentView);
+ return null;
}
/**
* @return The load progress of current web contents (range is 0 - 100).
*/
public int getProgress() {
- return mContentViewCore.getProgress();
+ if (mNativeContentView != 0) {
+ return (int) (100.0 * nativeGetLoadProgress(mNativeContentView));
+ }
+ return 100;
}
/**
* @return Whether the current WebContents has a previous navigation entry.
*/
public boolean canGoBack() {
- return mContentViewCore.canGoBack();
+ return mNativeContentView != 0 && nativeCanGoBack(mNativeContentView);
}
/**
* @return Whether the current WebContents has a navigation entry after the current one.
*/
public boolean canGoForward() {
- return mContentViewCore.canGoForward();
+ return mNativeContentView != 0 && nativeCanGoForward(mNativeContentView);
}
/**
@@ -242,7 +291,7 @@
* @return Whether we can move in history by given offset
*/
public boolean canGoToOffset(int offset) {
- return mContentViewCore.canGoToOffset(offset);
+ return mNativeContentView != 0 && nativeCanGoToOffset(mNativeContentView, offset);
}
/**
@@ -251,28 +300,28 @@
* @param offset The offset into the navigation history.
*/
public void goToOffset(int offset) {
- mContentViewCore.goToOffset(offset);
+ if (mNativeContentView != 0) nativeGoToOffset(mNativeContentView, offset);
}
/**
* Goes to the navigation entry before the current one.
*/
public void goBack() {
- mContentViewCore.goBack();
+ if (mNativeContentView != 0) nativeGoBack(mNativeContentView);
}
/**
* Goes to the navigation entry following the current one.
*/
public void goForward() {
- mContentViewCore.goForward();
+ if (mNativeContentView != 0) nativeGoForward(mNativeContentView);
}
/**
* Reload the current page.
*/
public void reload() {
- mContentViewCore.reload();
+ if (mNativeContentView != 0) nativeReload(mNativeContentView);
}
/**
@@ -280,25 +329,29 @@
* directions.
*/
public void clearHistory() {
- mContentViewCore.clearHistory();
+ if (mNativeContentView != 0) nativeClearHistory(mNativeContentView);
}
/**
* Start pinch zoom. You must call {@link #pinchEnd} to stop.
*/
void pinchBegin(long timeMs, int x, int y) {
- mContentViewCore.pinchBegin(timeMs, x, y);
+ if (mNativeContentView != 0) {
+ // TODO(tedchoc): Pass pinch begin to native.
+ }
}
/**
* Stop pinch zoom.
*/
void pinchEnd(long timeMs) {
- mContentViewCore.pinchEnd(timeMs);
+ if (mNativeContentView != 0) {
+ // TODO(tedchoc): Pass pinch end to native.
+ }
}
void setIgnoreSingleTap(boolean value) {
- mContentViewCore.setIgnoreSingleTap(value);
+ mIgnoreSingleTap = value;
}
/**
@@ -314,7 +367,9 @@
* coordinate.
*/
void pinchBy(long timeMs, int anchorX, int anchorY, float delta) {
- mContentViewCore.pinchBy(timeMs, anchorX, anchorY, delta);
+ if (mNativeContentView != 0) {
+ // TODO(tedchoc): Pass pinch by to native.
+ }
}
/**
@@ -328,41 +383,26 @@
* settings.
*/
public ContentSettings getContentSettings() {
- return mContentViewCore.getContentSettings();
+ return mContentSettings;
}
- // FrameLayout overrides.
-
- // Needed by ContentViewCore.InternalAccessDelegate
- @Override
- public boolean drawChild(Canvas canvas, View child, long drawingTime) {
- return super.drawChild(canvas, child, drawingTime);
+ private void initGestureDetectors(final Context context) {
+ try {
+ TraceEvent.begin();
+ // TODO(tedchoc): Upstream the rest of the initialization.
+ mZoomManager = new ZoomManager(context, this);
+ mZoomManager.updateMultiTouchSupport();
+ } finally {
+ TraceEvent.end();
+ }
}
- // Needed by ContentViewCore.InternalAccessDelegate
- @Override
- public void onScrollChanged(int l, int t, int oldl, int oldt) {
- super.onScrollChanged(l, t, oldl, oldt);
- }
-
- // End FrameLayout overrides.
-
- @Override
- public boolean awakenScrollBars(int startDelay, boolean invalidate) {
- return mContentViewCore.awakenScrollBars(startDelay, invalidate);
- }
-
- @Override
- public boolean awakenScrollBars() {
- return super.awakenScrollBars();
- }
-
void updateMultiTouchZoomSupport() {
- mContentViewCore.updateMultiTouchZoomSupport();
+ mZoomManager.updateMultiTouchSupport();
}
public boolean isMultiTouchZoomSupported() {
- return mContentViewCore.isMultiTouchZoomSupported();
+ return mZoomManager.isMultiTouchZoomSupported();
}
/**
@@ -376,12 +416,12 @@
// fact that a ContentViewDownloadDelegate will be used in preference to a
// DownloadListener.
public void setDownloadListener(DownloadListener listener) {
- mContentViewCore.setDownloadListener(listener);
+ mDownloadListener = listener;
}
// Called by DownloadController.
DownloadListener downloadListener() {
- return mContentViewCore.downloadListener();
+ return mDownloadListener;
}
/**
@@ -392,26 +432,27 @@
* @param listener An implementation of ContentViewDownloadDelegate.
*/
public void setDownloadDelegate(ContentViewDownloadDelegate delegate) {
- mContentViewCore.setDownloadDelegate(delegate);
+ mDownloadDelegate = delegate;
}
// Called by DownloadController.
ContentViewDownloadDelegate getDownloadDelegate() {
- return mContentViewCore.getDownloadDelegate();
+ return mDownloadDelegate;
}
/**
* @return Whether the native ContentView has crashed.
*/
public boolean isCrashed() {
- return mContentViewCore.isCrashed();
+ if (mNativeContentView == 0) return false;
+ return nativeCrashed(mNativeContentView);
}
/**
* @return Whether a reload happens when this ContentView is activated.
*/
public boolean needsReload() {
- return mContentViewCore.needsReload();
+ return mNativeContentView != 0 && nativeNeedsReload(mNativeContentView);
}
/**
@@ -422,7 +463,7 @@
// This method uses the term 'zoom' for legacy reasons, but relates
// to what chrome calls the 'page scale factor'.
public boolean canZoomIn() {
- return mContentViewCore.canZoomIn();
+ return mNativeMaximumScale - mNativePageScaleFactor > WEBVIEW_ZOOM_CONTROLS_EPSILON;
}
/**
@@ -433,7 +474,7 @@
// This method uses the term 'zoom' for legacy reasons, but relates
// to what chrome calls the 'page scale factor'.
public boolean canZoomOut() {
- return mContentViewCore.canZoomOut();
+ return mNativePageScaleFactor - mNativeMinimumScale > WEBVIEW_ZOOM_CONTROLS_EPSILON;
}
/**
@@ -445,7 +486,24 @@
// This method uses the term 'zoom' for legacy reasons, but relates
// to what chrome calls the 'page scale factor'.
public boolean zoomIn() {
- return mContentViewCore.zoomIn();
+ if (!canZoomIn()) {
+ return false;
+ }
+
+ if (mNativeContentView == 0) {
+ return false;
+ }
+
+ long timeMs = System.currentTimeMillis();
+ int x = getWidth() / 2;
+ int y = getHeight() / 2;
+ float delta = 1.25f;
+
+ pinchBegin(timeMs, x, y);
+ pinchBy(timeMs, x, y, delta);
+ pinchEnd(timeMs);
+
+ return true;
}
/**
@@ -457,55 +515,87 @@
// This method uses the term 'zoom' for legacy reasons, but relates
// to what chrome calls the 'page scale factor'.
public boolean zoomOut() {
- return mContentViewCore.zoomOut();
+ if (!canZoomOut()) {
+ return false;
+ }
+
+ if (mNativeContentView == 0) {
+ return false;
+ }
+
+ long timeMs = System.currentTimeMillis();
+ int x = getWidth() / 2;
+ int y = getHeight() / 2;
+ float delta = 0.8f;
+
+ pinchBegin(timeMs, x, y);
+ pinchBy(timeMs, x, y, delta);
+ pinchEnd(timeMs);
+
+ return true;
}
// Invokes the graphical zoom picker widget for this ContentView.
public void invokeZoomPicker() {
- mContentViewCore.invokeZoomPicker();
+ if (mContentSettings.supportZoom()) {
+ mZoomManager.invokeZoomPicker();
+ }
}
// Unlike legacy WebView getZoomControls which returns external zoom controls,
// this method returns built-in zoom controls. This method is used in tests.
public View getZoomControlsForTest() {
- return mContentViewCore.getZoomControlsForTest();
+ return mZoomManager.getZoomControlsViewForTest();
}
- ///////////////////////////////////////////////////////////////////////////////////////////////
- // Start Implementation of ContentViewCore.InternalAccessDelegate //
- ///////////////////////////////////////////////////////////////////////////////////////////////
+ /**
+ * Initialize the ContentView native side.
+ * Should be called with a valid native WebContents.
+ * If nativeInitProcess is never called, the first time this method is called, nativeInitProcess
+ * will be called implicitly with the default settings.
+ * @param webContentsPtr the ContentView does not create a new native WebContents and uses
+ * the provided one.
+ * @return a native pointer to the native ContentView object.
+ */
+ private native int nativeInit(int webContentsPtr);
- @Override
- public boolean super_onKeyUp(int keyCode, KeyEvent event) {
- return super.onKeyUp(keyCode, event);
- }
+ private native void nativeDestroy(int nativeContentViewImpl);
- @Override
- public boolean super_dispatchKeyEventPreIme(KeyEvent event) {
- return super.dispatchKeyEventPreIme(event);
- }
+ private native void nativeLoadUrlWithoutUrlSanitization(int nativeContentViewImpl,
+ String url, int pageTransition);
+ private native void nativeLoadUrlWithoutUrlSanitizationWithUserAgentOverride(
+ int nativeContentViewImpl, String url, int pageTransition, String userAgentOverride);
- @Override
- public boolean super_dispatchKeyEvent(KeyEvent event) {
- return super.dispatchKeyEvent(event);
- }
+ private native String nativeGetURL(int nativeContentViewImpl);
- @Override
- public boolean super_onGenericMotionEvent(MotionEvent event) {
- return super.onGenericMotionEvent(event);
- }
+ private native String nativeGetTitle(int nativeContentViewImpl);
- @Override
- public void super_onConfigurationChanged(Configuration newConfig) {
- super.onConfigurationChanged(newConfig);
- }
+ private native double nativeGetLoadProgress(int nativeContentViewImpl);
- @Override
- public boolean super_awakenScrollBars(int startDelay, boolean invalidate) {
- return super.awakenScrollBars(startDelay, invalidate);
- }
+ private native boolean nativeIsIncognito(int nativeContentViewImpl);
- ///////////////////////////////////////////////////////////////////////////////////////////////
- // End Implementation of ContentViewCore.InternalAccessDelegate //
- ///////////////////////////////////////////////////////////////////////////////////////////////
+ // Returns true if the native side crashed so that java side can draw a sad tab.
+ private native boolean nativeCrashed(int nativeContentViewImpl);
+
+ private native boolean nativeCanGoBack(int nativeContentViewImpl);
+
+ private native boolean nativeCanGoForward(int nativeContentViewImpl);
+
+ private native boolean nativeCanGoToOffset(int nativeContentViewImpl, int offset);
+
+ private native void nativeGoToOffset(int nativeContentViewImpl, int offset);
+
+ private native void nativeGoBack(int nativeContentViewImpl);
+
+ private native void nativeGoForward(int nativeContentViewImpl);
+
+ private native void nativeStopLoading(int nativeContentViewImpl);
+
+ private native void nativeReload(int nativeContentViewImpl);
+
+ private native void nativeSetClient(int nativeContentViewImpl, ContentViewClient client);
+
+ private native boolean nativeNeedsReload(int nativeContentViewImpl);
+
+ private native void nativeClearHistory(int nativeContentViewImpl);
}

Powered by Google App Engine
This is Rietveld 408576698