Index: content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java |
diff --git a/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java b/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java |
deleted file mode 100644 |
index ec600bcf0724103c93a4fdf1c3555a1ac2e6ca5c..0000000000000000000000000000000000000000 |
--- a/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java |
+++ /dev/null |
@@ -1,3452 +0,0 @@ |
-// Copyright 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.app.Activity; |
-import android.app.SearchManager; |
-import android.content.ContentResolver; |
-import android.content.Context; |
-import android.content.Intent; |
-import android.content.pm.ActivityInfo; |
-import android.content.pm.PackageManager; |
-import android.content.res.Configuration; |
-import android.database.ContentObserver; |
-import android.graphics.Bitmap; |
-import android.graphics.Canvas; |
-import android.graphics.Color; |
-import android.graphics.Rect; |
-import android.graphics.RectF; |
-import android.net.Uri; |
-import android.os.Build; |
-import android.os.Bundle; |
-import android.os.Handler; |
-import android.os.ResultReceiver; |
-import android.provider.Browser; |
-import android.provider.Settings; |
-import android.text.Editable; |
-import android.text.TextUtils; |
-import android.util.Log; |
-import android.util.Pair; |
-import android.view.ActionMode; |
-import android.view.HapticFeedbackConstants; |
-import android.view.InputDevice; |
-import android.view.KeyEvent; |
-import android.view.MotionEvent; |
-import android.view.Surface; |
-import android.view.View; |
-import android.view.ViewGroup; |
-import android.view.Window; |
-import android.view.WindowManager; |
-import android.view.accessibility.AccessibilityEvent; |
-import android.view.accessibility.AccessibilityManager; |
-import android.view.accessibility.AccessibilityManager.AccessibilityStateChangeListener; |
-import android.view.accessibility.AccessibilityNodeInfo; |
-import android.view.accessibility.AccessibilityNodeProvider; |
-import android.view.inputmethod.EditorInfo; |
-import android.view.inputmethod.InputConnection; |
-import android.view.inputmethod.InputMethodManager; |
-import android.widget.AbsoluteLayout; |
-import android.widget.FrameLayout; |
- |
-import com.google.common.annotations.VisibleForTesting; |
- |
-import org.chromium.base.CalledByNative; |
-import org.chromium.base.CommandLine; |
-import org.chromium.base.JNINamespace; |
-import org.chromium.base.TraceEvent; |
-import org.chromium.base.WeakContext; |
-import org.chromium.content.R; |
-import org.chromium.content.browser.ContentViewGestureHandler.MotionEventDelegate; |
-import org.chromium.content.browser.accessibility.AccessibilityInjector; |
-import org.chromium.content.browser.accessibility.BrowserAccessibilityManager; |
-import org.chromium.content.browser.input.AdapterInputConnection; |
-import org.chromium.content.browser.input.HandleView; |
-import org.chromium.content.browser.input.ImeAdapter; |
-import org.chromium.content.browser.input.ImeAdapter.AdapterInputConnectionFactory; |
-import org.chromium.content.browser.input.InputMethodManagerWrapper; |
-import org.chromium.content.browser.input.InsertionHandleController; |
-import org.chromium.content.browser.input.SelectPopupDialog; |
-import org.chromium.content.browser.input.SelectPopupItem; |
-import org.chromium.content.browser.input.SelectionHandleController; |
-import org.chromium.content.common.ContentSwitches; |
-import org.chromium.ui.base.ViewAndroid; |
-import org.chromium.ui.base.ViewAndroidDelegate; |
-import org.chromium.ui.base.WindowAndroid; |
-import org.chromium.ui.gfx.DeviceDisplayInfo; |
- |
-import java.lang.annotation.Annotation; |
-import java.lang.reflect.Field; |
-import java.util.ArrayList; |
-import java.util.HashMap; |
-import java.util.HashSet; |
-import java.util.List; |
-import java.util.Map; |
- |
-/** |
- * Provides a Java-side 'wrapper' around a WebContent (native) instance. |
- * Contains all the major functionality necessary to manage the lifecycle of a ContentView without |
- * being tied to the view system. |
- */ |
-@JNINamespace("content") |
-public class ContentViewCore |
- implements MotionEventDelegate, NavigationClient, AccessibilityStateChangeListener { |
- |
- private static final String TAG = "ContentViewCore"; |
- |
- // Used to avoid enabling zooming in / out if resulting zooming will |
- // produce little visible difference. |
- private static final float ZOOM_CONTROLS_EPSILON = 0.007f; |
- |
- // Used to represent gestures for long press and long tap. |
- private static final int IS_LONG_PRESS = 1; |
- private static final int IS_LONG_TAP = 2; |
- |
- // Length of the delay (in ms) before fading in handles after the last page movement. |
- private static final int TEXT_HANDLE_FADE_IN_DELAY = 300; |
- |
- // If the embedder adds a JavaScript interface object that contains an indirect reference to |
- // the ContentViewCore, then storing a strong ref to the interface object on the native |
- // side would prevent garbage collection of the ContentViewCore (as that strong ref would |
- // create a new GC root). |
- // For that reason, we store only a weak reference to the interface object on the |
- // native side. However we still need a strong reference on the Java side to |
- // prevent garbage collection if the embedder doesn't maintain their own ref to the |
- // interface object - the Java side ref won't create a new GC root. |
- // This map stores those refernces. We put into the map on addJavaScriptInterface() |
- // and remove from it in removeJavaScriptInterface(). |
- private final Map<String, Object> mJavaScriptInterfaces = new HashMap<String, Object>(); |
- |
- // Additionally, we keep track of all Java bound JS objects that are in use on the |
- // current page to ensure that they are not garbage collected until the page is |
- // navigated. This includes interface objects that have been removed |
- // via the removeJavaScriptInterface API and transient objects returned from methods |
- // on the interface object. Note we use HashSet rather than Set as the native side |
- // expects HashSet (no bindings for interfaces). |
- private final HashSet<Object> mRetainedJavaScriptObjects = new HashSet<Object>(); |
- |
- /** |
- * Interface that consumers of {@link ContentViewCore} must implement to allow the proper |
- * dispatching of view methods through the containing view. |
- * |
- * <p> |
- * All methods with the "super_" prefix should be routed to the parent of the |
- * implementing container view. |
- */ |
- @SuppressWarnings("javadoc") |
- public interface InternalAccessDelegate { |
- /** |
- * @see View#drawChild(Canvas, View, long) |
- */ |
- boolean drawChild(Canvas canvas, View child, long drawingTime); |
- |
- /** |
- * @see View#onKeyUp(keyCode, KeyEvent) |
- */ |
- boolean super_onKeyUp(int keyCode, KeyEvent event); |
- |
- /** |
- * @see View#dispatchKeyEventPreIme(KeyEvent) |
- */ |
- boolean super_dispatchKeyEventPreIme(KeyEvent event); |
- |
- /** |
- * @see View#dispatchKeyEvent(KeyEvent) |
- */ |
- boolean super_dispatchKeyEvent(KeyEvent event); |
- |
- /** |
- * @see View#onGenericMotionEvent(MotionEvent) |
- */ |
- boolean super_onGenericMotionEvent(MotionEvent event); |
- |
- /** |
- * @see View#onConfigurationChanged(Configuration) |
- */ |
- void super_onConfigurationChanged(Configuration newConfig); |
- |
- /** |
- * @see View#onScrollChanged(int, int, int, int) |
- */ |
- void onScrollChanged(int lPix, int tPix, int oldlPix, int oldtPix); |
- |
- /** |
- * @see View#awakenScrollBars() |
- */ |
- boolean awakenScrollBars(); |
- |
- /** |
- * @see View#awakenScrollBars(int, boolean) |
- */ |
- boolean super_awakenScrollBars(int startDelay, boolean invalidate); |
- } |
- |
- /** |
- * An interface that allows the embedder to be notified of events and state changes related to |
- * gesture processing. |
- */ |
- public interface GestureStateListener { |
- /** |
- * Called when the pinch gesture starts. |
- */ |
- void onPinchGestureStart(); |
- |
- /** |
- * Called when the pinch gesture ends. |
- */ |
- void onPinchGestureEnd(); |
- |
- /** |
- * Called when the fling gesture is sent. |
- */ |
- void onFlingStartGesture(int vx, int vy); |
- |
- /** |
- * Called when the fling cancel gesture is sent. |
- */ |
- void onFlingCancelGesture(); |
- |
- /** |
- * Called when a fling event was not handled by the renderer. |
- */ |
- void onUnhandledFlingStartEvent(); |
- |
- /** |
- * Called to indicate that a scroll update gesture had been consumed by the page. |
- * This callback is called whenever any layer is scrolled (like a frame or div). It is |
- * not called when a JS touch handler consumes the event (preventDefault), it is not called |
- * for JS-initiated scrolling. |
- */ |
- void onScrollUpdateGestureConsumed(); |
- } |
- |
- /** |
- * An interface for controlling visibility and state of embedder-provided zoom controls. |
- */ |
- public interface ZoomControlsDelegate { |
- /** |
- * Called when it's reasonable to show zoom controls. |
- */ |
- void invokeZoomPicker(); |
- |
- /** |
- * Called when zoom controls need to be hidden (e.g. when the view hides). |
- */ |
- void dismissZoomPicker(); |
- |
- /** |
- * Called when page scale has been changed, so the controls can update their state. |
- */ |
- void updateZoomControls(); |
- } |
- |
- /** |
- * An interface that allows the embedder to be notified of changes to the parameters of the |
- * currently displayed contents. |
- * These notifications are consistent with respect to the UI thread (the size is the size of |
- * the contents currently displayed on screen). |
- */ |
- public interface UpdateFrameInfoListener { |
- /** |
- * Called each time any of the parameters are changed. |
- * |
- * @param pageScaleFactor The page scale. |
- */ |
- void onFrameInfoUpdated(float pageScaleFactor); |
- } |
- |
- /** |
- * An interface that allows the embedder to be notified when the results of |
- * extractSmartClipData are available. |
- */ |
- public interface SmartClipDataListener { |
- public void onSmartClipDataExtracted(String result); |
- } |
- |
- private VSyncManager.Provider mVSyncProvider; |
- private VSyncManager.Listener mVSyncListener; |
- private int mVSyncSubscriberCount; |
- private boolean mVSyncListenerRegistered; |
- |
- // To avoid IPC delay we use input events to directly trigger a vsync signal in the renderer. |
- // When we do this, we also need to avoid sending the real vsync signal for the current |
- // frame to avoid double-ticking. This flag is used to inhibit the next vsync notification. |
- private boolean mDidSignalVSyncUsingInputEvent; |
- |
- public VSyncManager.Listener getVSyncListener(VSyncManager.Provider vsyncProvider) { |
- if (mVSyncProvider != null && mVSyncListenerRegistered) { |
- mVSyncProvider.unregisterVSyncListener(mVSyncListener); |
- mVSyncListenerRegistered = false; |
- } |
- |
- mVSyncProvider = vsyncProvider; |
- mVSyncListener = new VSyncManager.Listener() { |
- @Override |
- public void updateVSync(long tickTimeMicros, long intervalMicros) { |
- if (mNativeContentViewCore != 0) { |
- nativeUpdateVSyncParameters(mNativeContentViewCore, tickTimeMicros, |
- intervalMicros); |
- } |
- } |
- |
- @Override |
- public void onVSync(long frameTimeMicros) { |
- animateIfNecessary(frameTimeMicros); |
- |
- if (mRequestedVSyncForInput) { |
- mRequestedVSyncForInput = false; |
- removeVSyncSubscriber(); |
- } |
- if (mNativeContentViewCore != 0) { |
- nativeOnVSync(mNativeContentViewCore, frameTimeMicros); |
- } |
- } |
- }; |
- |
- if (mVSyncSubscriberCount > 0) { |
- // addVSyncSubscriber() is called before getVSyncListener. |
- vsyncProvider.registerVSyncListener(mVSyncListener); |
- mVSyncListenerRegistered = true; |
- } |
- |
- return mVSyncListener; |
- } |
- |
- @CalledByNative |
- void addVSyncSubscriber() { |
- if (!isVSyncNotificationEnabled()) { |
- mDidSignalVSyncUsingInputEvent = false; |
- } |
- if (mVSyncProvider != null && !mVSyncListenerRegistered) { |
- mVSyncProvider.registerVSyncListener(mVSyncListener); |
- mVSyncListenerRegistered = true; |
- } |
- mVSyncSubscriberCount++; |
- } |
- |
- @CalledByNative |
- void removeVSyncSubscriber() { |
- if (mVSyncProvider != null && mVSyncSubscriberCount == 1) { |
- assert mVSyncListenerRegistered; |
- mVSyncProvider.unregisterVSyncListener(mVSyncListener); |
- mVSyncListenerRegistered = false; |
- } |
- mVSyncSubscriberCount--; |
- assert mVSyncSubscriberCount >= 0; |
- } |
- |
- @CalledByNative |
- private void resetVSyncNotification() { |
- while (isVSyncNotificationEnabled()) removeVSyncSubscriber(); |
- mVSyncSubscriberCount = 0; |
- mVSyncListenerRegistered = false; |
- mNeedAnimate = false; |
- } |
- |
- private boolean isVSyncNotificationEnabled() { |
- return mVSyncProvider != null && mVSyncListenerRegistered; |
- } |
- |
- @CalledByNative |
- private void setNeedsAnimate() { |
- if (!mNeedAnimate) { |
- mNeedAnimate = true; |
- addVSyncSubscriber(); |
- } |
- } |
- |
- private final Context mContext; |
- private ViewGroup mContainerView; |
- private InternalAccessDelegate mContainerViewInternals; |
- private WebContents mWebContents; |
- private WebContentsObserverAndroid mWebContentsObserver; |
- |
- private ContentViewClient mContentViewClient; |
- |
- private ContentSettings mContentSettings; |
- |
- // Native pointer to C++ ContentViewCoreImpl object which will be set by nativeInit(). |
- private long mNativeContentViewCore = 0; |
- |
- private boolean mInForeground = false; |
- |
- private ContentViewGestureHandler mContentViewGestureHandler; |
- private GestureStateListener mGestureStateListener; |
- private ZoomManager mZoomManager; |
- private ZoomControlsDelegate mZoomControlsDelegate; |
- |
- private PopupZoomer mPopupZoomer; |
- |
- private Runnable mFakeMouseMoveRunnable = null; |
- |
- // Only valid when focused on a text / password field. |
- private ImeAdapter mImeAdapter; |
- private ImeAdapter.AdapterInputConnectionFactory mAdapterInputConnectionFactory; |
- private AdapterInputConnection mInputConnection; |
- |
- private SelectionHandleController mSelectionHandleController; |
- private InsertionHandleController mInsertionHandleController; |
- |
- private Runnable mDeferredHandleFadeInRunnable; |
- |
- private PositionObserver mPositionObserver; |
- private PositionObserver.Listener mPositionListener; |
- |
- // Size of the viewport in physical pixels as set from onSizeChanged. |
- private int mViewportWidthPix; |
- private int mViewportHeightPix; |
- private int mPhysicalBackingWidthPix; |
- private int mPhysicalBackingHeightPix; |
- private int mOverdrawBottomHeightPix; |
- private int mViewportSizeOffsetWidthPix; |
- private int mViewportSizeOffsetHeightPix; |
- private int mLocationInWindowX; |
- private int mLocationInWindowY; |
- |
- // Cached copy of all positions and scales as reported by the renderer. |
- private final RenderCoordinates mRenderCoordinates; |
- |
- private final RenderCoordinates.NormalizedPoint mStartHandlePoint; |
- private final RenderCoordinates.NormalizedPoint mEndHandlePoint; |
- private final RenderCoordinates.NormalizedPoint mInsertionHandlePoint; |
- |
- // Tracks whether a selection is currently active. When applied to selected text, indicates |
- // whether the last selected text is still highlighted. |
- private boolean mHasSelection; |
- private String mLastSelectedText; |
- private boolean mSelectionEditable; |
- private ActionMode mActionMode; |
- private boolean mUnselectAllOnActionModeDismiss; |
- |
- // Delegate that will handle GET downloads, and be notified of completion of POST downloads. |
- private ContentViewDownloadDelegate mDownloadDelegate; |
- |
- // The AccessibilityInjector that handles loading Accessibility scripts into the web page. |
- private AccessibilityInjector mAccessibilityInjector; |
- |
- // Whether native accessibility, i.e. without any script injection, is allowed. |
- private boolean mNativeAccessibilityAllowed; |
- |
- // Whether native accessibility, i.e. without any script injection, has been enabled. |
- private boolean mNativeAccessibilityEnabled; |
- |
- // Handles native accessibility, i.e. without any script injection. |
- private BrowserAccessibilityManager mBrowserAccessibilityManager; |
- |
- // System accessibility service. |
- private final AccessibilityManager mAccessibilityManager; |
- |
- // Allows us to dynamically respond when the accessibility script injection flag changes. |
- private ContentObserver mAccessibilityScriptInjectionObserver; |
- |
- // Temporary notification to tell onSizeChanged to focus a form element, |
- // because the OSK was just brought up. |
- private boolean mUnfocusOnNextSizeChanged = false; |
- private final Rect mFocusPreOSKViewportRect = new Rect(); |
- |
- // Used to keep track of whether we should try to undo the last zoom-to-textfield operation. |
- private boolean mScrolledAndZoomedFocusedEditableNode = false; |
- |
- // Whether we use hardware-accelerated drawing. |
- private boolean mHardwareAccelerated = false; |
- |
- // Whether we received a new frame since consumePendingRendererFrame() was last called. |
- private boolean mPendingRendererFrame = false; |
- |
- // Whether we should animate at the next vsync tick. |
- private boolean mNeedAnimate = false; |
- |
- // Whether we requested a proactive vsync event in response to touch input. |
- // This reduces the latency of responding to input by ensuring the renderer |
- // is sent a BeginFrame for every touch event we receive. Otherwise the |
- // renderer's SetNeedsBeginFrame message would get serviced at the next |
- // vsync. |
- private boolean mRequestedVSyncForInput = false; |
- |
- private ViewAndroid mViewAndroid; |
- |
- private SmartClipDataListener mSmartClipDataListener = null; |
- |
- /** ActionAfterDoubleTap defined in tools/metrics/histograms/histograms.xml. */ |
- public static class UMAActionAfterDoubleTap { |
- public static final int NAVIGATE_BACK = 0; |
- public static final int NAVIGATE_STOP = 1; |
- public static final int NO_ACTION = 2; |
- public static final int COUNT = 3; |
- } |
- |
- /** TapDelayType defined in tools/metrics/histograms/histograms.xml. */ |
- public static class UMASingleTapType { |
- public static final int DELAYED_TAP = 0; |
- public static final int UNDELAYED_TAP = 1; |
- public static final int COUNT = 2; |
- } |
- |
- /** |
- * Constructs a new ContentViewCore. Embedders must call initialize() after constructing |
- * a ContentViewCore and before using it. |
- * |
- * @param context The context used to create this. |
- */ |
- public ContentViewCore(Context context) { |
- mContext = context; |
- |
- WeakContext.initializeWeakContext(context); |
- HeapStatsLogger.init(mContext.getApplicationContext()); |
- mAdapterInputConnectionFactory = new AdapterInputConnectionFactory(); |
- |
- mRenderCoordinates = new RenderCoordinates(); |
- mRenderCoordinates.setDeviceScaleFactor( |
- getContext().getResources().getDisplayMetrics().density); |
- mStartHandlePoint = mRenderCoordinates.createNormalizedPoint(); |
- mEndHandlePoint = mRenderCoordinates.createNormalizedPoint(); |
- mInsertionHandlePoint = mRenderCoordinates.createNormalizedPoint(); |
- mAccessibilityManager = (AccessibilityManager) |
- getContext().getSystemService(Context.ACCESSIBILITY_SERVICE); |
- } |
- |
- /** |
- * @return The context used for creating this ContentViewCore. |
- */ |
- @CalledByNative |
- public Context getContext() { |
- return mContext; |
- } |
- |
- /** |
- * @return The ViewGroup that all view actions of this ContentViewCore should interact with. |
- */ |
- public ViewGroup getContainerView() { |
- return mContainerView; |
- } |
- |
- /** |
- * @return The WebContents currently being rendered. |
- */ |
- public WebContents getWebContents() { |
- return mWebContents; |
- } |
- |
- /** |
- * Specifies how much smaller the WebKit layout size should be relative to the size of this |
- * view. |
- * @param offsetXPix The X amount in pixels to shrink the viewport by. |
- * @param offsetYPix The Y amount in pixels to shrink the viewport by. |
- */ |
- public void setViewportSizeOffset(int offsetXPix, int offsetYPix) { |
- if (offsetXPix != mViewportSizeOffsetWidthPix || |
- offsetYPix != mViewportSizeOffsetHeightPix) { |
- mViewportSizeOffsetWidthPix = offsetXPix; |
- mViewportSizeOffsetHeightPix = offsetYPix; |
- if (mNativeContentViewCore != 0) nativeWasResized(mNativeContentViewCore); |
- } |
- } |
- |
- /** |
- * Returns a delegate that can be used to add and remove views from the ContainerView. |
- * |
- * NOTE: Use with care, as not all ContentViewCore users setup their ContainerView in the same |
- * way. In particular, the Android WebView has limitations on what implementation details can |
- * be provided via a child view, as they are visible in the API and could introduce |
- * compatibility breaks with existing applications. If in doubt, contact the |
- * android_webview/OWNERS |
- * |
- * @return A ViewAndroidDelegate that can be used to add and remove views. |
- */ |
- @VisibleForTesting |
- public ViewAndroidDelegate getViewAndroidDelegate() { |
- return new ViewAndroidDelegate() { |
- @Override |
- public View acquireAnchorView() { |
- View anchorView = new View(getContext()); |
- mContainerView.addView(anchorView); |
- return anchorView; |
- } |
- |
- @Override |
- @SuppressWarnings("deprecation") // AbsoluteLayout.LayoutParams |
- public void setAnchorViewPosition( |
- View view, float x, float y, float width, float height) { |
- assert view.getParent() == mContainerView; |
- |
- float scale = (float) DeviceDisplayInfo.create(getContext()).getDIPScale(); |
- |
- // The anchor view should not go outside the bounds of the ContainerView. |
- int leftMargin = Math.round(x * scale); |
- int topMargin = Math.round(mRenderCoordinates.getContentOffsetYPix() + y * scale); |
- int scaledWidth = Math.round(width * scale); |
- // ContentViewCore currently only supports these two container view types. |
- if (mContainerView instanceof FrameLayout) { |
- if (scaledWidth + leftMargin > mContainerView.getWidth()) { |
- scaledWidth = mContainerView.getWidth() - leftMargin; |
- } |
- FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams( |
- scaledWidth, Math.round(height * scale)); |
- lp.leftMargin = leftMargin; |
- lp.topMargin = topMargin; |
- view.setLayoutParams(lp); |
- } else if (mContainerView instanceof AbsoluteLayout) { |
- // This fixes the offset due to a difference in |
- // scrolling model of WebView vs. Chrome. |
- // TODO(sgurun) fix this to use mContainerView.getScroll[X/Y]() |
- // as it naturally accounts for scroll differences between |
- // these models. |
- leftMargin += mRenderCoordinates.getScrollXPixInt(); |
- topMargin += mRenderCoordinates.getScrollYPixInt(); |
- |
- android.widget.AbsoluteLayout.LayoutParams lp = |
- new android.widget.AbsoluteLayout.LayoutParams( |
- scaledWidth, (int) (height * scale), leftMargin, topMargin); |
- view.setLayoutParams(lp); |
- } else { |
- Log.e(TAG, "Unknown layout " + mContainerView.getClass().getName()); |
- } |
- } |
- |
- @Override |
- public void releaseAnchorView(View anchorView) { |
- mContainerView.removeView(anchorView); |
- } |
- }; |
- } |
- |
- @VisibleForTesting |
- public ImeAdapter getImeAdapterForTest() { |
- return mImeAdapter; |
- } |
- |
- @VisibleForTesting |
- public void setAdapterInputConnectionFactory(AdapterInputConnectionFactory factory) { |
- mAdapterInputConnectionFactory = factory; |
- } |
- |
- @VisibleForTesting |
- public AdapterInputConnection getInputConnectionForTest() { |
- return mInputConnection; |
- } |
- |
- private ImeAdapter createImeAdapter(Context context) { |
- return new ImeAdapter(new InputMethodManagerWrapper(context), |
- new ImeAdapter.ImeAdapterDelegate() { |
- @Override |
- public void onImeEvent(boolean isFinish) { |
- getContentViewClient().onImeEvent(); |
- if (!isFinish) { |
- hideHandles(); |
- undoScrollFocusedEditableNodeIntoViewIfNeeded(false); |
- } |
- } |
- |
- @Override |
- public void onSetFieldValue() { |
- scrollFocusedEditableNodeIntoView(); |
- } |
- |
- @Override |
- public void onDismissInput() { |
- getContentViewClient().onImeStateChangeRequested(false); |
- } |
- |
- @Override |
- public View getAttachedView() { |
- return mContainerView; |
- } |
- |
- @Override |
- public ResultReceiver getNewShowKeyboardReceiver() { |
- return new ResultReceiver(new Handler()) { |
- @Override |
- public void onReceiveResult(int resultCode, Bundle resultData) { |
- getContentViewClient().onImeStateChangeRequested( |
- resultCode == InputMethodManager.RESULT_SHOWN || |
- resultCode == InputMethodManager.RESULT_UNCHANGED_SHOWN); |
- if (resultCode == InputMethodManager.RESULT_SHOWN) { |
- // If OSK is newly shown, delay the form focus until |
- // the onSizeChanged (in order to adjust relative to the |
- // new size). |
- // TODO(jdduke): We should not assume that onSizeChanged will |
- // always be called, crbug.com/294908. |
- getContainerView().getWindowVisibleDisplayFrame( |
- mFocusPreOSKViewportRect); |
- } else if (resultCode == |
- InputMethodManager.RESULT_UNCHANGED_SHOWN) { |
- // If the OSK was already there, focus the form immediately. |
- scrollFocusedEditableNodeIntoView(); |
- } else { |
- undoScrollFocusedEditableNodeIntoViewIfNeeded(false); |
- } |
- } |
- }; |
- } |
- } |
- ); |
- } |
- |
- /** |
- * Returns true if the given Activity has hardware acceleration enabled |
- * in its manifest, or in its foreground window. |
- * |
- * TODO(husky): Remove when initialize() is refactored (see TODO there) |
- * TODO(dtrainor) This is still used by other classes. Make sure to pull some version of this |
- * out before removing it. |
- */ |
- public static boolean hasHardwareAcceleration(Activity activity) { |
- // Has HW acceleration been enabled manually in the current window? |
- Window window = activity.getWindow(); |
- if (window != null) { |
- if ((window.getAttributes().flags |
- & WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED) != 0) { |
- return true; |
- } |
- } |
- |
- // Has HW acceleration been enabled in the manifest? |
- try { |
- ActivityInfo info = activity.getPackageManager().getActivityInfo( |
- activity.getComponentName(), 0); |
- if ((info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0) { |
- return true; |
- } |
- } catch (PackageManager.NameNotFoundException e) { |
- Log.e("Chrome", "getActivityInfo(self) should not fail"); |
- } |
- |
- return false; |
- } |
- |
- /** |
- * Returns true if the given Context is a HW-accelerated Activity. |
- * |
- * TODO(husky): Remove when initialize() is refactored (see TODO there) |
- */ |
- private static boolean hasHardwareAcceleration(Context context) { |
- if (context instanceof Activity) { |
- return hasHardwareAcceleration((Activity) context); |
- } |
- return false; |
- } |
- |
- /** |
- * |
- * @param containerView The view that will act as a container for all views created by this. |
- * @param internalDispatcher Handles dispatching all hidden or super methods to the |
- * containerView. |
- * @param nativeWebContents A pointer to the native web contents. |
- * @param windowAndroid An instance of the WindowAndroid. |
- */ |
- // Perform important post-construction set up of the ContentViewCore. |
- // We do not require the containing view in the constructor to allow embedders to create a |
- // ContentViewCore without having fully created its containing view. The containing view |
- // is a vital component of the ContentViewCore, so embedders must exercise caution in what |
- // they do with the ContentViewCore before calling initialize(). |
- // We supply the nativeWebContents pointer here rather than in the constructor to allow us |
- // to set the private browsing mode at a later point for the WebView implementation. |
- // Note that the caller remains the owner of the nativeWebContents and is responsible for |
- // deleting it after destroying the ContentViewCore. |
- public void initialize(ViewGroup containerView, InternalAccessDelegate internalDispatcher, |
- long nativeWebContents, WindowAndroid windowAndroid) { |
- // Check whether to use hardware acceleration. This is a bit hacky, and |
- // only works if the Context is actually an Activity (as it is in the |
- // Chrome application). |
- // |
- // What we're doing here is checking whether the app has *requested* |
- // hardware acceleration by setting the appropriate flags. This does not |
- // necessarily mean we're going to *get* hardware acceleration -- that's |
- // up to the Android framework. |
- // |
- // TODO(husky): Once the native code has been updated so that the |
- // HW acceleration flag can be set dynamically (Grace is doing this), |
- // move this check into onAttachedToWindow(), where we can test for |
- // HW support directly. |
- mHardwareAccelerated = hasHardwareAcceleration(mContext); |
- |
- mContainerView = containerView; |
- mPositionObserver = new ViewPositionObserver(mContainerView); |
- mPositionListener = new PositionObserver.Listener() { |
- @Override |
- public void onPositionChanged(int x, int y) { |
- if (isSelectionHandleShowing() || isInsertionHandleShowing()) { |
- temporarilyHideTextHandles(); |
- } |
- } |
- }; |
- |
- long windowNativePointer = windowAndroid != null ? windowAndroid.getNativePointer() : 0; |
- |
- long viewAndroidNativePointer = 0; |
- if (windowNativePointer != 0) { |
- mViewAndroid = new ViewAndroid(windowAndroid, getViewAndroidDelegate()); |
- viewAndroidNativePointer = mViewAndroid.getNativePointer(); |
- } |
- |
- mNativeContentViewCore = nativeInit(mHardwareAccelerated, |
- nativeWebContents, viewAndroidNativePointer, windowNativePointer); |
- mWebContents = nativeGetWebContentsAndroid(mNativeContentViewCore); |
- mContentSettings = new ContentSettings(this, mNativeContentViewCore); |
- initializeContainerView(internalDispatcher); |
- |
- mAccessibilityInjector = AccessibilityInjector.newInstance(this); |
- |
- String contentDescription = "Web View"; |
- if (R.string.accessibility_content_view == 0) { |
- Log.w(TAG, "Setting contentDescription to 'Web View' as no value was specified."); |
- } else { |
- contentDescription = mContext.getResources().getString( |
- R.string.accessibility_content_view); |
- } |
- mContainerView.setContentDescription(contentDescription); |
- mWebContentsObserver = new WebContentsObserverAndroid(this) { |
- @Override |
- public void didStartLoading(String url) { |
- hidePopupDialog(); |
- resetGestureDetectors(); |
- } |
- }; |
- |
- sendOrientationChangeEvent(); |
- } |
- |
- @CalledByNative |
- void onNativeContentViewCoreDestroyed(long nativeContentViewCore) { |
- assert nativeContentViewCore == mNativeContentViewCore; |
- mNativeContentViewCore = 0; |
- } |
- |
- /** |
- * Set the Container view Internals. |
- * @param internalDispatcher Handles dispatching all hidden or super methods to the |
- * containerView. |
- */ |
- public void setContainerViewInternals(InternalAccessDelegate internalDispatcher) { |
- mContainerViewInternals = internalDispatcher; |
- } |
- |
- /** |
- * Initializes the View that will contain all Views created by the ContentViewCore. |
- * |
- * @param internalDispatcher Handles dispatching all hidden or super methods to the |
- * containerView. |
- */ |
- private void initializeContainerView(InternalAccessDelegate internalDispatcher) { |
- TraceEvent.begin(); |
- mContainerViewInternals = internalDispatcher; |
- |
- mContainerView.setWillNotDraw(false); |
- mContainerView.setClickable(true); |
- |
- mZoomManager = new ZoomManager(mContext, this); |
- mContentViewGestureHandler = new ContentViewGestureHandler(mContext, this, mZoomManager); |
- mZoomControlsDelegate = new ZoomControlsDelegate() { |
- @Override |
- public void invokeZoomPicker() {} |
- @Override |
- public void dismissZoomPicker() {} |
- @Override |
- public void updateZoomControls() {} |
- }; |
- |
- mRenderCoordinates.reset(); |
- onRenderCoordinatesUpdated(); |
- |
- initPopupZoomer(mContext); |
- mImeAdapter = createImeAdapter(mContext); |
- TraceEvent.end(); |
- } |
- |
- private void initPopupZoomer(Context context) { |
- mPopupZoomer = new PopupZoomer(context); |
- mPopupZoomer.setOnVisibilityChangedListener(new PopupZoomer.OnVisibilityChangedListener() { |
- @Override |
- public void onPopupZoomerShown(final PopupZoomer zoomer) { |
- mContainerView.post(new Runnable() { |
- @Override |
- public void run() { |
- if (mContainerView.indexOfChild(zoomer) == -1) { |
- mContainerView.addView(zoomer); |
- } else { |
- assert false : "PopupZoomer should never be shown without being hidden"; |
- } |
- } |
- }); |
- } |
- |
- @Override |
- public void onPopupZoomerHidden(final PopupZoomer zoomer) { |
- mContainerView.post(new Runnable() { |
- @Override |
- public void run() { |
- if (mContainerView.indexOfChild(zoomer) != -1) { |
- mContainerView.removeView(zoomer); |
- mContainerView.invalidate(); |
- } else { |
- assert false : "PopupZoomer should never be hidden without being shown"; |
- } |
- } |
- }); |
- } |
- }); |
- // TODO(yongsheng): LONG_TAP is not enabled in PopupZoomer. So need to dispatch a LONG_TAP |
- // gesture if a user completes a tap on PopupZoomer UI after a LONG_PRESS gesture. |
- PopupZoomer.OnTapListener listener = new PopupZoomer.OnTapListener() { |
- @Override |
- public boolean onSingleTap(View v, MotionEvent e) { |
- mContainerView.requestFocus(); |
- if (mNativeContentViewCore != 0) { |
- nativeSingleTap(mNativeContentViewCore, e.getEventTime(), |
- e.getX(), e.getY(), true); |
- } |
- return true; |
- } |
- |
- @Override |
- public boolean onLongPress(View v, MotionEvent e) { |
- if (mNativeContentViewCore != 0) { |
- nativeLongPress(mNativeContentViewCore, e.getEventTime(), |
- e.getX(), e.getY(), true); |
- } |
- return true; |
- } |
- }; |
- mPopupZoomer.setOnTapListener(listener); |
- } |
- |
- /** |
- * Destroy the internal state of the ContentView. This method may only be |
- * called after the ContentView has been removed from the view system. No |
- * other methods may be called on this ContentView after this method has |
- * been called. |
- */ |
- public void destroy() { |
- if (mNativeContentViewCore != 0) { |
- nativeOnJavaContentViewCoreDestroyed(mNativeContentViewCore); |
- } |
- mWebContents = null; |
- resetVSyncNotification(); |
- mVSyncProvider = null; |
- if (mViewAndroid != null) mViewAndroid.destroy(); |
- mNativeContentViewCore = 0; |
- mContentSettings = null; |
- mJavaScriptInterfaces.clear(); |
- mRetainedJavaScriptObjects.clear(); |
- unregisterAccessibilityContentObserver(); |
- } |
- |
- private void unregisterAccessibilityContentObserver() { |
- if (mAccessibilityScriptInjectionObserver == null) { |
- return; |
- } |
- getContext().getContentResolver().unregisterContentObserver( |
- mAccessibilityScriptInjectionObserver); |
- mAccessibilityScriptInjectionObserver = null; |
- } |
- |
- /** |
- * Returns true initially, false after destroy() has been called. |
- * It is illegal to call any other public method after destroy(). |
- */ |
- public boolean isAlive() { |
- return mNativeContentViewCore != 0; |
- } |
- |
- /** |
- * This is only useful for passing over JNI to native code that requires ContentViewCore*. |
- * @return native ContentViewCore pointer. |
- */ |
- @CalledByNative |
- public long getNativeContentViewCore() { |
- return mNativeContentViewCore; |
- } |
- |
- /** |
- * For internal use. Throws IllegalStateException if mNativeContentView is 0. |
- * Use this to ensure we get a useful Java stack trace, rather than a native |
- * crash dump, from use-after-destroy bugs in Java code. |
- */ |
- void checkIsAlive() throws IllegalStateException { |
- if (!isAlive()) { |
- throw new IllegalStateException("ContentView used after destroy() was called"); |
- } |
- } |
- |
- public void setContentViewClient(ContentViewClient client) { |
- if (client == null) { |
- throw new IllegalArgumentException("The client can't be null."); |
- } |
- mContentViewClient = client; |
- } |
- |
- ContentViewClient 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; |
- } |
- |
- public int getBackgroundColor() { |
- if (mNativeContentViewCore != 0) { |
- return nativeGetBackgroundColor(mNativeContentViewCore); |
- } |
- return Color.WHITE; |
- } |
- |
- @CalledByNative |
- private void onBackgroundColorChanged(int color) { |
- getContentViewClient().onBackgroundColorChanged(color); |
- } |
- |
- /** |
- * Load url without fixing up the url string. Consumers of ContentView are responsible for |
- * ensuring the URL passed in is properly formatted (i.e. the scheme has been added if left |
- * off during user input). |
- * |
- * @param params Parameters for this load. |
- */ |
- public void loadUrl(LoadUrlParams params) { |
- if (mNativeContentViewCore == 0) return; |
- |
- nativeLoadUrl(mNativeContentViewCore, |
- params.mUrl, |
- params.mLoadUrlType, |
- params.mTransitionType, |
- params.mUaOverrideOption, |
- params.getExtraHeadersString(), |
- params.mPostData, |
- params.mBaseUrlForDataUrl, |
- params.mVirtualUrlForDataUrl, |
- params.mCanLoadLocalResources); |
- } |
- |
- /** |
- * Stops loading the current web contents. |
- */ |
- public void stopLoading() { |
- reportActionAfterDoubleTapUMA(ContentViewCore.UMAActionAfterDoubleTap.NAVIGATE_STOP); |
- if (mNativeContentViewCore != 0) nativeStopLoading(mNativeContentViewCore); |
- } |
- |
- /** |
- * Get the URL of the current page. |
- * |
- * @return The URL of the current page. |
- */ |
- public String getUrl() { |
- if (mNativeContentViewCore != 0) return nativeGetURL(mNativeContentViewCore); |
- return null; |
- } |
- |
- /** |
- * Get the title of the current page. |
- * |
- * @return The title of the current page. |
- */ |
- public String getTitle() { |
- if (mNativeContentViewCore != 0) return nativeGetTitle(mNativeContentViewCore); |
- return null; |
- } |
- |
- /** |
- * Shows an interstitial page driven by the passed in delegate. |
- * |
- * @param url The URL being blocked by the interstitial. |
- * @param delegate The delegate handling the interstitial. |
- */ |
- @VisibleForTesting |
- public void showInterstitialPage( |
- String url, InterstitialPageDelegateAndroid delegate) { |
- if (mNativeContentViewCore == 0) return; |
- nativeShowInterstitialPage(mNativeContentViewCore, url, delegate.getNative()); |
- } |
- |
- /** |
- * @return Whether the page is currently showing an interstitial, such as a bad HTTPS page. |
- */ |
- public boolean isShowingInterstitialPage() { |
- return mNativeContentViewCore == 0 ? |
- false : nativeIsShowingInterstitialPage(mNativeContentViewCore); |
- } |
- |
- /** |
- * Mark any new frames that have arrived since this function was last called as non-pending. |
- * |
- * @return Whether there was a pending frame from the renderer. |
- */ |
- public boolean consumePendingRendererFrame() { |
- boolean hadPendingFrame = mPendingRendererFrame; |
- mPendingRendererFrame = false; |
- return hadPendingFrame; |
- } |
- |
- /** |
- * @return Viewport width in physical pixels as set from onSizeChanged. |
- */ |
- @CalledByNative |
- public int getViewportWidthPix() { return mViewportWidthPix; } |
- |
- /** |
- * @return Viewport height in physical pixels as set from onSizeChanged. |
- */ |
- @CalledByNative |
- public int getViewportHeightPix() { return mViewportHeightPix; } |
- |
- /** |
- * @return Width of underlying physical surface. |
- */ |
- @CalledByNative |
- public int getPhysicalBackingWidthPix() { return mPhysicalBackingWidthPix; } |
- |
- /** |
- * @return Height of underlying physical surface. |
- */ |
- @CalledByNative |
- public int getPhysicalBackingHeightPix() { return mPhysicalBackingHeightPix; } |
- |
- /** |
- * @return Amount the output surface extends past the bottom of the window viewport. |
- */ |
- @CalledByNative |
- public int getOverdrawBottomHeightPix() { return mOverdrawBottomHeightPix; } |
- |
- /** |
- * @return The amount to shrink the viewport relative to {@link #getViewportWidthPix()}. |
- */ |
- @CalledByNative |
- public int getViewportSizeOffsetWidthPix() { return mViewportSizeOffsetWidthPix; } |
- |
- /** |
- * @return The amount to shrink the viewport relative to {@link #getViewportHeightPix()}. |
- */ |
- @CalledByNative |
- public int getViewportSizeOffsetHeightPix() { return mViewportSizeOffsetHeightPix; } |
- |
- /** |
- * @see android.webkit.WebView#getContentHeight() |
- */ |
- public float getContentHeightCss() { |
- return mRenderCoordinates.getContentHeightCss(); |
- } |
- |
- /** |
- * @see android.webkit.WebView#getContentWidth() |
- */ |
- public float getContentWidthCss() { |
- return mRenderCoordinates.getContentWidthCss(); |
- } |
- |
- public Bitmap getBitmap() { |
- return getBitmap(getViewportWidthPix(), getViewportHeightPix()); |
- } |
- |
- public Bitmap getBitmap(int width, int height) { |
- if (width == 0 || height == 0 |
- || getViewportWidthPix() == 0 || getViewportHeightPix() == 0) { |
- return null; |
- } |
- |
- Bitmap b = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); |
- |
- if (mNativeContentViewCore != 0 && |
- nativePopulateBitmapFromCompositor(mNativeContentViewCore, b)) { |
- // If we successfully grabbed a bitmap, check if we have to draw the Android overlay |
- // components as well. |
- if (mContainerView.getChildCount() > 0) { |
- Canvas c = new Canvas(b); |
- c.scale(width / (float) getViewportWidthPix(), |
- height / (float) getViewportHeightPix()); |
- mContainerView.draw(c); |
- } |
- return b; |
- } |
- |
- return null; |
- } |
- |
- /** |
- * Generates a bitmap of the content that is performance optimized based on capture time. |
- * |
- * <p> |
- * To have a consistent capture time across devices, we will scale down the captured bitmap |
- * where necessary to reduce the time to generate the bitmap. |
- * |
- * @param width The width of the content to be captured. |
- * @param height The height of the content to be captured. |
- * @return A pair of the generated bitmap, and the scale that needs to be applied to return the |
- * bitmap to it's original size (i.e. if the bitmap is scaled down 50%, this |
- * will be 2). |
- */ |
- public Pair<Bitmap, Float> getScaledPerformanceOptimizedBitmap(int width, int height) { |
- float scale = 1f; |
- // On tablets, always scale down to MDPI for performance reasons. |
- if (DeviceUtils.isTablet(getContext())) { |
- scale = getContext().getResources().getDisplayMetrics().density; |
- } |
- return Pair.create( |
- getBitmap((int) (width / scale), (int) (height / scale)), |
- scale); |
- } |
- |
- // TODO(teddchoc): Remove all these navigation controller methods from here and have the |
- // embedders manage it. |
- /** |
- * @return Whether the current WebContents has a previous navigation entry. |
- */ |
- public boolean canGoBack() { |
- return mWebContents != null && mWebContents.getNavigationController().canGoBack(); |
- } |
- |
- /** |
- * @return Whether the current WebContents has a navigation entry after the current one. |
- */ |
- public boolean canGoForward() { |
- return mWebContents != null && mWebContents.getNavigationController().canGoForward(); |
- } |
- |
- /** |
- * @param offset The offset into the navigation history. |
- * @return Whether we can move in history by given offset |
- */ |
- public boolean canGoToOffset(int offset) { |
- return mWebContents != null && |
- mWebContents.getNavigationController().canGoToOffset(offset); |
- } |
- |
- /** |
- * Navigates to the specified offset from the "current entry". Does nothing if the offset is out |
- * of bounds. |
- * @param offset The offset into the navigation history. |
- */ |
- public void goToOffset(int offset) { |
- if (mWebContents != null) mWebContents.getNavigationController().goToOffset(offset); |
- } |
- |
- @Override |
- public void goToNavigationIndex(int index) { |
- if (mWebContents != null) { |
- mWebContents.getNavigationController().goToNavigationIndex(index); |
- } |
- } |
- |
- /** |
- * Goes to the navigation entry before the current one. |
- */ |
- public void goBack() { |
- if (mWebContents != null) mWebContents.getNavigationController().goBack(); |
- } |
- |
- /** |
- * Goes to the navigation entry following the current one. |
- */ |
- public void goForward() { |
- if (mWebContents != null) mWebContents.getNavigationController().goForward(); |
- } |
- |
- /** |
- * Loads the current navigation if there is a pending lazy load (after tab restore). |
- */ |
- public void loadIfNecessary() { |
- if (mNativeContentViewCore != 0) nativeLoadIfNecessary(mNativeContentViewCore); |
- } |
- |
- /** |
- * Requests the current navigation to be loaded upon the next call to loadIfNecessary(). |
- */ |
- public void requestRestoreLoad() { |
- if (mNativeContentViewCore != 0) nativeRequestRestoreLoad(mNativeContentViewCore); |
- } |
- |
- /** |
- * Reload the current page. |
- */ |
- public void reload(boolean checkForRepost) { |
- mAccessibilityInjector.addOrRemoveAccessibilityApisIfNecessary(); |
- if (mNativeContentViewCore != 0) { |
- nativeReload(mNativeContentViewCore, checkForRepost); |
- } |
- } |
- |
- /** |
- * Reload the current page, ignoring the contents of the cache. |
- */ |
- public void reloadIgnoringCache(boolean checkForRepost) { |
- mAccessibilityInjector.addOrRemoveAccessibilityApisIfNecessary(); |
- if (mNativeContentViewCore != 0) { |
- nativeReloadIgnoringCache(mNativeContentViewCore, checkForRepost); |
- } |
- } |
- |
- /** |
- * Cancel the pending reload. |
- */ |
- public void cancelPendingReload() { |
- if (mNativeContentViewCore != 0) nativeCancelPendingReload(mNativeContentViewCore); |
- } |
- |
- /** |
- * Continue the pending reload. |
- */ |
- public void continuePendingReload() { |
- if (mNativeContentViewCore != 0) nativeContinuePendingReload(mNativeContentViewCore); |
- } |
- |
- /** |
- * Clears the ContentViewCore's page history in both the backwards and |
- * forwards directions. |
- */ |
- public void clearHistory() { |
- if (mNativeContentViewCore != 0) nativeClearHistory(mNativeContentViewCore); |
- } |
- |
- /** |
- * @return The selected text (empty if no text selected). |
- */ |
- public String getSelectedText() { |
- return mHasSelection ? mLastSelectedText : ""; |
- } |
- |
- /** |
- * @return Whether the current selection is editable (false if no text selected). |
- */ |
- public boolean isSelectionEditable() { |
- return mHasSelection ? mSelectionEditable : false; |
- } |
- |
- // End FrameLayout overrides. |
- |
- /** |
- * @see View#onTouchEvent(MotionEvent) |
- */ |
- public boolean onTouchEvent(MotionEvent event) { |
- undoScrollFocusedEditableNodeIntoViewIfNeeded(false); |
- if (!mRequestedVSyncForInput) { |
- mRequestedVSyncForInput = true; |
- addVSyncSubscriber(); |
- } |
- return mContentViewGestureHandler.onTouchEvent(event); |
- } |
- |
- /** |
- * @return ContentViewGestureHandler for all MotionEvent and gesture related calls. |
- */ |
- ContentViewGestureHandler getContentViewGestureHandler() { |
- return mContentViewGestureHandler; |
- } |
- |
- @Override |
- public boolean sendTouchEvent(long timeMs, int action, TouchPoint[] pts) { |
- if (mNativeContentViewCore != 0) { |
- return nativeSendTouchEvent(mNativeContentViewCore, timeMs, action, pts); |
- } |
- return false; |
- } |
- |
- @SuppressWarnings("unused") |
- @CalledByNative |
- private void hasTouchEventHandlers(boolean hasTouchHandlers) { |
- mContentViewGestureHandler.hasTouchEventHandlers(hasTouchHandlers); |
- } |
- |
- @SuppressWarnings("unused") |
- @CalledByNative |
- private void confirmTouchEvent(int ackResult) { |
- mContentViewGestureHandler.confirmTouchEvent(ackResult); |
- } |
- |
- @SuppressWarnings("unused") |
- @CalledByNative |
- private void onFlingStartEventAck(int ackResult) { |
- if (ackResult == ContentViewGestureHandler.INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS |
- && mGestureStateListener != null) { |
- mGestureStateListener.onUnhandledFlingStartEvent(); |
- } |
- if (ackResult != ContentViewGestureHandler.INPUT_EVENT_ACK_STATE_CONSUMED) { |
- // No fling happened for the fling start event. |
- // Cancel the fling status set when sending GestureFlingStart. |
- getContentViewClient().onFlingStopped(); |
- } |
- } |
- |
- @SuppressWarnings("unused") |
- @CalledByNative |
- private void onScrollUpdateGestureConsumed() { |
- if (mGestureStateListener != null) { |
- mGestureStateListener.onScrollUpdateGestureConsumed(); |
- } |
- } |
- |
- private void reportActionAfterDoubleTapUMA(int type) { |
- mContentViewGestureHandler.reportActionAfterDoubleTapUMA(type); |
- } |
- |
- @Override |
- public boolean sendGesture(int type, long timeMs, int x, int y, Bundle b) { |
- if (offerGestureToEmbedder(type)) return false; |
- if (mNativeContentViewCore == 0) return false; |
- updateTextHandlesForGesture(type); |
- updateGestureStateListener(type, b); |
- switch (type) { |
- case ContentViewGestureHandler.GESTURE_SHOW_PRESSED_STATE: |
- nativeShowPressState(mNativeContentViewCore, timeMs, x, y); |
- return true; |
- case ContentViewGestureHandler.GESTURE_TAP_CANCEL: |
- nativeTapCancel(mNativeContentViewCore, timeMs, x, y); |
- return true; |
- case ContentViewGestureHandler.GESTURE_TAP_DOWN: |
- nativeTapDown(mNativeContentViewCore, timeMs, x, y); |
- return true; |
- case ContentViewGestureHandler.GESTURE_DOUBLE_TAP: |
- nativeDoubleTap(mNativeContentViewCore, timeMs, x, y); |
- return true; |
- case ContentViewGestureHandler.GESTURE_SINGLE_TAP_UP: |
- nativeSingleTap(mNativeContentViewCore, timeMs, x, y, false); |
- return true; |
- case ContentViewGestureHandler.GESTURE_SINGLE_TAP_CONFIRMED: |
- handleTapOrPress(timeMs, x, y, 0, |
- b.getBoolean(ContentViewGestureHandler.SHOW_PRESS, false)); |
- return true; |
- case ContentViewGestureHandler.GESTURE_SINGLE_TAP_UNCONFIRMED: |
- nativeSingleTapUnconfirmed(mNativeContentViewCore, timeMs, x, y); |
- return true; |
- case ContentViewGestureHandler.GESTURE_LONG_PRESS: |
- handleTapOrPress(timeMs, x, y, IS_LONG_PRESS, false); |
- return true; |
- case ContentViewGestureHandler.GESTURE_LONG_TAP: |
- handleTapOrPress(timeMs, x, y, IS_LONG_TAP, false); |
- return true; |
- case ContentViewGestureHandler.GESTURE_SCROLL_START: { |
- int dx = b.getInt(ContentViewGestureHandler.DELTA_HINT_X); |
- int dy = b.getInt(ContentViewGestureHandler.DELTA_HINT_Y); |
- nativeScrollBegin(mNativeContentViewCore, timeMs, x, y, dx, dy); |
- return true; |
- } |
- case ContentViewGestureHandler.GESTURE_SCROLL_BY: { |
- int dx = b.getInt(ContentViewGestureHandler.DISTANCE_X); |
- int dy = b.getInt(ContentViewGestureHandler.DISTANCE_Y); |
- nativeScrollBy(mNativeContentViewCore, timeMs, x, y, dx, dy); |
- return true; |
- } |
- case ContentViewGestureHandler.GESTURE_SCROLL_END: |
- nativeScrollEnd(mNativeContentViewCore, timeMs); |
- return true; |
- case ContentViewGestureHandler.GESTURE_FLING_START: |
- mContentViewClient.onFlingStarted(); |
- nativeFlingStart(mNativeContentViewCore, timeMs, x, y, |
- b.getInt(ContentViewGestureHandler.VELOCITY_X, 0), |
- b.getInt(ContentViewGestureHandler.VELOCITY_Y, 0)); |
- return true; |
- case ContentViewGestureHandler.GESTURE_FLING_CANCEL: |
- nativeFlingCancel(mNativeContentViewCore, timeMs); |
- return true; |
- case ContentViewGestureHandler.GESTURE_PINCH_BEGIN: |
- nativePinchBegin(mNativeContentViewCore, timeMs, x, y); |
- return true; |
- case ContentViewGestureHandler.GESTURE_PINCH_BY: |
- nativePinchBy(mNativeContentViewCore, timeMs, x, y, |
- b.getFloat(ContentViewGestureHandler.DELTA, 0)); |
- return true; |
- case ContentViewGestureHandler.GESTURE_PINCH_END: |
- nativePinchEnd(mNativeContentViewCore, timeMs); |
- return true; |
- default: |
- return false; |
- } |
- } |
- |
- @VisibleForTesting |
- public void sendDoubleTapForTest(long timeMs, int x, int y, Bundle b) { |
- sendGesture(ContentViewGestureHandler.GESTURE_DOUBLE_TAP, timeMs, x, y, b); |
- } |
- |
- @Override |
- public void sendSingleTapUMA(int type) { |
- if (mNativeContentViewCore == 0) return; |
- nativeSendSingleTapUma( |
- mNativeContentViewCore, |
- type, |
- UMASingleTapType.COUNT); |
- } |
- |
- @Override |
- public void sendActionAfterDoubleTapUMA(int type, |
- boolean clickDelayEnabled) { |
- if (mNativeContentViewCore == 0) return; |
- nativeSendActionAfterDoubleTapUma( |
- mNativeContentViewCore, |
- type, |
- clickDelayEnabled, |
- UMAActionAfterDoubleTap.COUNT); |
- } |
- |
- public void setGestureStateListener(GestureStateListener pinchGestureStateListener) { |
- mGestureStateListener = pinchGestureStateListener; |
- } |
- |
- void updateGestureStateListener(int gestureType, Bundle b) { |
- if (mGestureStateListener == null) return; |
- |
- switch (gestureType) { |
- case ContentViewGestureHandler.GESTURE_PINCH_BEGIN: |
- mGestureStateListener.onPinchGestureStart(); |
- break; |
- case ContentViewGestureHandler.GESTURE_PINCH_END: |
- mGestureStateListener.onPinchGestureEnd(); |
- break; |
- case ContentViewGestureHandler.GESTURE_FLING_START: |
- mGestureStateListener.onFlingStartGesture( |
- b.getInt(ContentViewGestureHandler.VELOCITY_X, 0), |
- b.getInt(ContentViewGestureHandler.VELOCITY_Y, 0)); |
- break; |
- case ContentViewGestureHandler.GESTURE_FLING_CANCEL: |
- mGestureStateListener.onFlingCancelGesture(); |
- break; |
- default: |
- break; |
- } |
- } |
- |
- /** Callback interface for evaluateJavaScript(). */ |
- public interface JavaScriptCallback { |
- void handleJavaScriptResult(String jsonResult); |
- } |
- |
- /** |
- * Injects the passed Javascript code in the current page and evaluates it. |
- * If a result is required, pass in a callback. |
- * Used in automation tests. |
- * |
- * @param script The Javascript to execute. |
- * @param callback The callback to be fired off when a result is ready. The script's |
- * result will be json encoded and passed as the parameter, and the call |
- * will be made on the main thread. |
- * If no result is required, pass null. |
- */ |
- public void evaluateJavaScript(String script, JavaScriptCallback callback) { |
- if (mNativeContentViewCore == 0) return; |
- nativeEvaluateJavaScript(mNativeContentViewCore, script, callback, false); |
- } |
- |
- /** |
- * Injects the passed Javascript code in the current page and evaluates it. |
- * If there is no page existing, a new one will be created. |
- * |
- * @param script The Javascript to execute. |
- */ |
- public void evaluateJavaScriptEvenIfNotYetNavigated(String script) { |
- if (mNativeContentViewCore == 0) return; |
- nativeEvaluateJavaScript(mNativeContentViewCore, script, null, true); |
- } |
- |
- /** |
- * To be called when the ContentView is shown. |
- */ |
- public void onShow() { |
- assert mNativeContentViewCore != 0; |
- if (!mInForeground) { |
- int pid = nativeGetCurrentRenderProcessId(mNativeContentViewCore); |
- ChildProcessLauncher.getBindingManager().setInForeground(pid, true); |
- } |
- mInForeground = true; |
- nativeOnShow(mNativeContentViewCore); |
- setAccessibilityState(mAccessibilityManager.isEnabled()); |
- } |
- |
- /** |
- * To be called when the ContentView is hidden. |
- */ |
- public void onHide() { |
- assert mNativeContentViewCore != 0; |
- if (mInForeground) { |
- int pid = nativeGetCurrentRenderProcessId(mNativeContentViewCore); |
- ChildProcessLauncher.getBindingManager().setInForeground(pid, false); |
- } |
- mInForeground = false; |
- hidePopupDialog(); |
- setInjectedAccessibility(false); |
- nativeOnHide(mNativeContentViewCore); |
- } |
- |
- /** |
- * Return the ContentSettings object used to retrieve the settings for this |
- * ContentViewCore. For modifications, ChromeNativePreferences is to be used. |
- * @return A ContentSettings object that can be used to retrieve this |
- * ContentViewCore's settings. |
- */ |
- public ContentSettings getContentSettings() { |
- return mContentSettings; |
- } |
- |
- private void onRenderCoordinatesUpdated() { |
- if (mContentViewGestureHandler == null) return; |
- |
- // We disable double tap zoom for pages that have a width=device-width |
- // or narrower viewport (indicating that this is a mobile-optimized or |
- // responsive web design, so text will be legible without zooming). |
- // We also disable it for pages that disallow the user from zooming in |
- // or out (even if they don't have a device-width or narrower viewport). |
- mContentViewGestureHandler.updateShouldDisableDoubleTap( |
- mRenderCoordinates.hasMobileViewport() || mRenderCoordinates.hasFixedPageScale()); |
- } |
- |
- private void hidePopupDialog() { |
- SelectPopupDialog.hide(this); |
- hideHandles(); |
- hideSelectActionBar(); |
- } |
- |
- void hideSelectActionBar() { |
- if (mActionMode != null) { |
- mActionMode.finish(); |
- mActionMode = null; |
- } |
- } |
- |
- public boolean isSelectActionBarShowing() { |
- return mActionMode != null; |
- } |
- |
- private void resetGestureDetectors() { |
- mContentViewGestureHandler.resetGestureHandlers(); |
- } |
- |
- /** |
- * @see View#onAttachedToWindow() |
- */ |
- @SuppressWarnings("javadoc") |
- public void onAttachedToWindow() { |
- setAccessibilityState(mAccessibilityManager.isEnabled()); |
- } |
- |
- /** |
- * @see View#onDetachedFromWindow() |
- */ |
- @SuppressWarnings("javadoc") |
- public void onDetachedFromWindow() { |
- setInjectedAccessibility(false); |
- hidePopupDialog(); |
- mZoomControlsDelegate.dismissZoomPicker(); |
- unregisterAccessibilityContentObserver(); |
- } |
- |
- /** |
- * @see View#onVisibilityChanged(android.view.View, int) |
- */ |
- public void onVisibilityChanged(View changedView, int visibility) { |
- if (visibility != View.VISIBLE) { |
- mZoomControlsDelegate.dismissZoomPicker(); |
- } |
- } |
- |
- /** |
- * @see View#onCreateInputConnection(EditorInfo) |
- */ |
- public InputConnection onCreateInputConnection(EditorInfo outAttrs) { |
- if (!mImeAdapter.hasTextInputType()) { |
- // Although onCheckIsTextEditor will return false in this case, the EditorInfo |
- // is still used by the InputMethodService. Need to make sure the IME doesn't |
- // enter fullscreen mode. |
- outAttrs.imeOptions = EditorInfo.IME_FLAG_NO_FULLSCREEN; |
- } |
- mInputConnection = |
- mAdapterInputConnectionFactory.get(mContainerView, mImeAdapter, outAttrs); |
- return mInputConnection; |
- } |
- |
- public Editable getEditableForTest() { |
- return mInputConnection.getEditable(); |
- } |
- |
- /** |
- * @see View#onCheckIsTextEditor() |
- */ |
- public boolean onCheckIsTextEditor() { |
- return mImeAdapter.hasTextInputType(); |
- } |
- |
- /** |
- * @see View#onConfigurationChanged(Configuration) |
- */ |
- @SuppressWarnings("javadoc") |
- public void onConfigurationChanged(Configuration newConfig) { |
- TraceEvent.begin(); |
- |
- if (newConfig.keyboard != Configuration.KEYBOARD_NOKEYS) { |
- mImeAdapter.attach(nativeGetNativeImeAdapter(mNativeContentViewCore), |
- ImeAdapter.getTextInputTypeNone(), |
- AdapterInputConnection.INVALID_SELECTION, |
- AdapterInputConnection.INVALID_SELECTION); |
- InputMethodManager manager = (InputMethodManager) |
- getContext().getSystemService(Context.INPUT_METHOD_SERVICE); |
- manager.restartInput(mContainerView); |
- } |
- mContainerViewInternals.super_onConfigurationChanged(newConfig); |
- // Make sure the size is up to date in JavaScript's window.onorientationchanged. |
- mContainerView.addOnLayoutChangeListener(new View.OnLayoutChangeListener() { |
- @Override |
- public void onLayoutChange(View v, int left, int top, int right, int bottom, |
- int oldLeft, int oldTop, int oldRight, int oldBottom) { |
- mContainerView.removeOnLayoutChangeListener(this); |
- sendOrientationChangeEvent(); |
- } |
- }); |
- // To request layout has side effect, but it seems OK as it only happen in |
- // onConfigurationChange and layout has to be changed in most case. |
- mContainerView.requestLayout(); |
- TraceEvent.end(); |
- } |
- |
- /** |
- * @see View#onSizeChanged(int, int, int, int) |
- */ |
- @SuppressWarnings("javadoc") |
- public void onSizeChanged(int wPix, int hPix, int owPix, int ohPix) { |
- if (getViewportWidthPix() == wPix && getViewportHeightPix() == hPix) return; |
- |
- mViewportWidthPix = wPix; |
- mViewportHeightPix = hPix; |
- if (mNativeContentViewCore != 0) { |
- nativeWasResized(mNativeContentViewCore); |
- } |
- |
- updateAfterSizeChanged(); |
- } |
- |
- /** |
- * Called when the ContentView's position in the activity window changed. This information is |
- * used for cropping screenshots. |
- */ |
- public void onLocationInWindowChanged(int x, int y) { |
- mLocationInWindowX = x; |
- mLocationInWindowY = y; |
- } |
- |
- /** |
- * Called when the underlying surface the compositor draws to changes size. |
- * This may be larger than the viewport size. |
- */ |
- public void onPhysicalBackingSizeChanged(int wPix, int hPix) { |
- if (mPhysicalBackingWidthPix == wPix && mPhysicalBackingHeightPix == hPix) return; |
- |
- mPhysicalBackingWidthPix = wPix; |
- mPhysicalBackingHeightPix = hPix; |
- |
- if (mNativeContentViewCore != 0) { |
- nativeWasResized(mNativeContentViewCore); |
- } |
- } |
- |
- /** |
- * Called when the amount the surface is overdrawing off the bottom has changed. |
- * @param overdrawHeightPix The overdraw height. |
- */ |
- public void onOverdrawBottomHeightChanged(int overdrawHeightPix) { |
- if (mOverdrawBottomHeightPix == overdrawHeightPix) return; |
- |
- mOverdrawBottomHeightPix = overdrawHeightPix; |
- |
- if (mNativeContentViewCore != 0) { |
- nativeWasResized(mNativeContentViewCore); |
- } |
- } |
- |
- private void updateAfterSizeChanged() { |
- mPopupZoomer.hide(false); |
- |
- // Execute a delayed form focus operation because the OSK was brought |
- // up earlier. |
- if (!mFocusPreOSKViewportRect.isEmpty()) { |
- Rect rect = new Rect(); |
- getContainerView().getWindowVisibleDisplayFrame(rect); |
- if (!rect.equals(mFocusPreOSKViewportRect)) { |
- // Only assume the OSK triggered the onSizeChanged if width was preserved. |
- if (rect.width() == mFocusPreOSKViewportRect.width()) { |
- scrollFocusedEditableNodeIntoView(); |
- } |
- mFocusPreOSKViewportRect.setEmpty(); |
- } |
- } else if (mUnfocusOnNextSizeChanged) { |
- undoScrollFocusedEditableNodeIntoViewIfNeeded(true); |
- mUnfocusOnNextSizeChanged = false; |
- } |
- } |
- |
- private void scrollFocusedEditableNodeIntoView() { |
- if (mNativeContentViewCore != 0) { |
- Runnable scrollTask = new Runnable() { |
- @Override |
- public void run() { |
- if (mNativeContentViewCore != 0) { |
- nativeScrollFocusedEditableNodeIntoView(mNativeContentViewCore); |
- } |
- } |
- }; |
- |
- scrollTask.run(); |
- |
- // The native side keeps track of whether the zoom and scroll actually occurred. It is |
- // more efficient to do it this way and sometimes fire an unnecessary message rather |
- // than synchronize with the renderer and always have an additional message. |
- mScrolledAndZoomedFocusedEditableNode = true; |
- } |
- } |
- |
- private void undoScrollFocusedEditableNodeIntoViewIfNeeded(boolean backButtonPressed) { |
- // The only call to this function that matters is the first call after the |
- // scrollFocusedEditableNodeIntoView function call. |
- // If the first call to this function is a result of a back button press we want to undo the |
- // preceding scroll. If the call is a result of some other action we don't want to perform |
- // an undo. |
- // All subsequent calls are ignored since only the scroll function sets |
- // mScrolledAndZoomedFocusedEditableNode to true. |
- if (mScrolledAndZoomedFocusedEditableNode && backButtonPressed && |
- mNativeContentViewCore != 0) { |
- Runnable scrollTask = new Runnable() { |
- @Override |
- public void run() { |
- if (mNativeContentViewCore != 0) { |
- nativeUndoScrollFocusedEditableNodeIntoView(mNativeContentViewCore); |
- } |
- } |
- }; |
- |
- scrollTask.run(); |
- } |
- mScrolledAndZoomedFocusedEditableNode = false; |
- } |
- |
- /** |
- * @see View#onWindowFocusChanged(boolean) |
- */ |
- public void onWindowFocusChanged(boolean hasWindowFocus) { |
- if (!hasWindowFocus) { |
- mContentViewGestureHandler.onWindowFocusLost(); |
- } |
- } |
- |
- public void onFocusChanged(boolean gainFocus) { |
- if (!gainFocus) getContentViewClient().onImeStateChangeRequested(false); |
- if (mNativeContentViewCore != 0) nativeSetFocus(mNativeContentViewCore, gainFocus); |
- } |
- |
- /** |
- * @see View#onKeyUp(int, KeyEvent) |
- */ |
- public boolean onKeyUp(int keyCode, KeyEvent event) { |
- if (mPopupZoomer.isShowing() && keyCode == KeyEvent.KEYCODE_BACK) { |
- mPopupZoomer.hide(true); |
- return true; |
- } |
- return mContainerViewInternals.super_onKeyUp(keyCode, event); |
- } |
- |
- /** |
- * @see View#dispatchKeyEventPreIme(KeyEvent) |
- */ |
- public boolean dispatchKeyEventPreIme(KeyEvent event) { |
- try { |
- TraceEvent.begin(); |
- if (event.getKeyCode() == KeyEvent.KEYCODE_BACK && mImeAdapter.isActive()) { |
- mUnfocusOnNextSizeChanged = true; |
- } else { |
- undoScrollFocusedEditableNodeIntoViewIfNeeded(false); |
- } |
- return mContainerViewInternals.super_dispatchKeyEventPreIme(event); |
- } finally { |
- TraceEvent.end(); |
- } |
- } |
- |
- /** |
- * @see View#dispatchKeyEvent(KeyEvent) |
- */ |
- public boolean dispatchKeyEvent(KeyEvent event) { |
- if (getContentViewClient().shouldOverrideKeyEvent(event)) { |
- return mContainerViewInternals.super_dispatchKeyEvent(event); |
- } |
- |
- if (mImeAdapter.dispatchKeyEvent(event)) return true; |
- |
- return mContainerViewInternals.super_dispatchKeyEvent(event); |
- } |
- |
- /** |
- * @see View#onHoverEvent(MotionEvent) |
- * Mouse move events are sent on hover enter, hover move and hover exit. |
- * They are sent on hover exit because sometimes it acts as both a hover |
- * move and hover exit. |
- */ |
- public boolean onHoverEvent(MotionEvent event) { |
- TraceEvent.begin("onHoverEvent"); |
- mContainerView.removeCallbacks(mFakeMouseMoveRunnable); |
- if (mBrowserAccessibilityManager != null) { |
- return mBrowserAccessibilityManager.onHoverEvent(event); |
- } |
- if (mNativeContentViewCore != 0) { |
- nativeSendMouseMoveEvent(mNativeContentViewCore, event.getEventTime(), |
- event.getX(), event.getY()); |
- } |
- TraceEvent.end("onHoverEvent"); |
- return true; |
- } |
- |
- /** |
- * @see View#onGenericMotionEvent(MotionEvent) |
- */ |
- public boolean onGenericMotionEvent(MotionEvent event) { |
- if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) { |
- switch (event.getAction()) { |
- case MotionEvent.ACTION_SCROLL: |
- nativeSendMouseWheelEvent(mNativeContentViewCore, event.getEventTime(), |
- event.getX(), event.getY(), |
- event.getAxisValue(MotionEvent.AXIS_VSCROLL)); |
- |
- mContainerView.removeCallbacks(mFakeMouseMoveRunnable); |
- // Send a delayed onMouseMove event so that we end |
- // up hovering over the right position after the scroll. |
- final MotionEvent eventFakeMouseMove = MotionEvent.obtain(event); |
- mFakeMouseMoveRunnable = new Runnable() { |
- @Override |
- public void run() { |
- onHoverEvent(eventFakeMouseMove); |
- } |
- }; |
- mContainerView.postDelayed(mFakeMouseMoveRunnable, 250); |
- return true; |
- } |
- } |
- return mContainerViewInternals.super_onGenericMotionEvent(event); |
- } |
- |
- /** |
- * @see View#scrollBy(int, int) |
- * Currently the ContentView scrolling happens in the native side. In |
- * the Java view system, it is always pinned at (0, 0). scrollBy() and scrollTo() |
- * are overridden, so that View's mScrollX and mScrollY will be unchanged at |
- * (0, 0). This is critical for drawing ContentView correctly. |
- */ |
- public void scrollBy(int xPix, int yPix) { |
- if (mNativeContentViewCore != 0) { |
- nativeScrollBy(mNativeContentViewCore, |
- System.currentTimeMillis(), 0, 0, xPix, yPix); |
- } |
- } |
- |
- /** |
- * @see View#scrollTo(int, int) |
- */ |
- public void scrollTo(int xPix, int yPix) { |
- if (mNativeContentViewCore == 0) return; |
- final float xCurrentPix = mRenderCoordinates.getScrollXPix(); |
- final float yCurrentPix = mRenderCoordinates.getScrollYPix(); |
- final float dxPix = xPix - xCurrentPix; |
- final float dyPix = yPix - yCurrentPix; |
- if (dxPix != 0 || dyPix != 0) { |
- long time = System.currentTimeMillis(); |
- nativeScrollBegin(mNativeContentViewCore, time, |
- xCurrentPix, yCurrentPix, -dxPix, -dyPix); |
- nativeScrollBy(mNativeContentViewCore, |
- time, xCurrentPix, yCurrentPix, dxPix, dyPix); |
- nativeScrollEnd(mNativeContentViewCore, time); |
- } |
- } |
- |
- // NOTE: this can go away once ContentView.getScrollX() reports correct values. |
- // see: b/6029133 |
- public int getNativeScrollXForTest() { |
- return mRenderCoordinates.getScrollXPixInt(); |
- } |
- |
- // NOTE: this can go away once ContentView.getScrollY() reports correct values. |
- // see: b/6029133 |
- public int getNativeScrollYForTest() { |
- return mRenderCoordinates.getScrollYPixInt(); |
- } |
- |
- /** |
- * @see View#computeHorizontalScrollExtent() |
- */ |
- @SuppressWarnings("javadoc") |
- public int computeHorizontalScrollExtent() { |
- return mRenderCoordinates.getLastFrameViewportWidthPixInt(); |
- } |
- |
- /** |
- * @see View#computeHorizontalScrollOffset() |
- */ |
- @SuppressWarnings("javadoc") |
- public int computeHorizontalScrollOffset() { |
- return mRenderCoordinates.getScrollXPixInt(); |
- } |
- |
- /** |
- * @see View#computeHorizontalScrollRange() |
- */ |
- @SuppressWarnings("javadoc") |
- public int computeHorizontalScrollRange() { |
- return mRenderCoordinates.getContentWidthPixInt(); |
- } |
- |
- /** |
- * @see View#computeVerticalScrollExtent() |
- */ |
- @SuppressWarnings("javadoc") |
- public int computeVerticalScrollExtent() { |
- return mRenderCoordinates.getLastFrameViewportHeightPixInt(); |
- } |
- |
- /** |
- * @see View#computeVerticalScrollOffset() |
- */ |
- @SuppressWarnings("javadoc") |
- public int computeVerticalScrollOffset() { |
- return mRenderCoordinates.getScrollYPixInt(); |
- } |
- |
- /** |
- * @see View#computeVerticalScrollRange() |
- */ |
- @SuppressWarnings("javadoc") |
- public int computeVerticalScrollRange() { |
- return mRenderCoordinates.getContentHeightPixInt(); |
- } |
- |
- // End FrameLayout overrides. |
- |
- /** |
- * @see View#awakenScrollBars(int, boolean) |
- */ |
- @SuppressWarnings("javadoc") |
- public boolean awakenScrollBars(int startDelay, boolean invalidate) { |
- // For the default implementation of ContentView which draws the scrollBars on the native |
- // side, calling this function may get us into a bad state where we keep drawing the |
- // scrollBars, so disable it by always returning false. |
- if (mContainerView.getScrollBarStyle() == View.SCROLLBARS_INSIDE_OVERLAY) { |
- return false; |
- } else { |
- return mContainerViewInternals.super_awakenScrollBars(startDelay, invalidate); |
- } |
- } |
- |
- private void handleTapOrPress( |
- long timeMs, float xPix, float yPix, int isLongPressOrTap, boolean showPress) { |
- if (mContainerView.isFocusable() && mContainerView.isFocusableInTouchMode() |
- && !mContainerView.isFocused()) { |
- mContainerView.requestFocus(); |
- } |
- |
- if (!mPopupZoomer.isShowing()) mPopupZoomer.setLastTouch(xPix, yPix); |
- |
- if (isLongPressOrTap == IS_LONG_PRESS) { |
- getInsertionHandleController().allowAutomaticShowing(); |
- getSelectionHandleController().allowAutomaticShowing(); |
- if (mNativeContentViewCore != 0) { |
- nativeLongPress(mNativeContentViewCore, timeMs, xPix, yPix, false); |
- } |
- } else if (isLongPressOrTap == IS_LONG_TAP) { |
- getInsertionHandleController().allowAutomaticShowing(); |
- getSelectionHandleController().allowAutomaticShowing(); |
- if (mNativeContentViewCore != 0) { |
- nativeLongTap(mNativeContentViewCore, timeMs, xPix, yPix, false); |
- } |
- } else { |
- if (!showPress && mNativeContentViewCore != 0) { |
- nativeShowPressState(mNativeContentViewCore, timeMs, xPix, yPix); |
- } |
- if (mSelectionEditable) getInsertionHandleController().allowAutomaticShowing(); |
- if (mNativeContentViewCore != 0) { |
- nativeSingleTap(mNativeContentViewCore, timeMs, xPix, yPix, false); |
- } |
- } |
- } |
- |
- public void setZoomControlsDelegate(ZoomControlsDelegate zoomControlsDelegate) { |
- mZoomControlsDelegate = zoomControlsDelegate; |
- } |
- |
- public void updateMultiTouchZoomSupport(boolean supportsMultiTouchZoom) { |
- mZoomManager.updateMultiTouchSupport(supportsMultiTouchZoom); |
- } |
- |
- public void updateDoubleTapSupport(boolean supportsDoubleTap) { |
- mContentViewGestureHandler.updateDoubleTapSupport(supportsDoubleTap); |
- } |
- |
- public void selectPopupMenuItems(int[] indices) { |
- if (mNativeContentViewCore != 0) { |
- nativeSelectPopupMenuItems(mNativeContentViewCore, indices); |
- } |
- } |
- |
- /** |
- * Get the screen orientation from the OS and push it to WebKit. |
- * |
- * TODO(husky): Add a hook for mock orientations. |
- */ |
- private void sendOrientationChangeEvent() { |
- if (mNativeContentViewCore == 0) return; |
- |
- WindowManager windowManager = |
- (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE); |
- switch (windowManager.getDefaultDisplay().getRotation()) { |
- case Surface.ROTATION_90: |
- nativeSendOrientationChangeEvent(mNativeContentViewCore, 90); |
- break; |
- case Surface.ROTATION_180: |
- nativeSendOrientationChangeEvent(mNativeContentViewCore, 180); |
- break; |
- case Surface.ROTATION_270: |
- nativeSendOrientationChangeEvent(mNativeContentViewCore, -90); |
- break; |
- case Surface.ROTATION_0: |
- nativeSendOrientationChangeEvent(mNativeContentViewCore, 0); |
- break; |
- default: |
- Log.w(TAG, "Unknown rotation!"); |
- break; |
- } |
- } |
- |
- /** |
- * Register the delegate to be used when content can not be handled by |
- * the rendering engine, and should be downloaded instead. This will replace |
- * the current delegate, if any. |
- * @param delegate An implementation of ContentViewDownloadDelegate. |
- */ |
- public void setDownloadDelegate(ContentViewDownloadDelegate delegate) { |
- mDownloadDelegate = delegate; |
- } |
- |
- // Called by DownloadController. |
- ContentViewDownloadDelegate getDownloadDelegate() { |
- return mDownloadDelegate; |
- } |
- |
- private SelectionHandleController getSelectionHandleController() { |
- if (mSelectionHandleController == null) { |
- mSelectionHandleController = new SelectionHandleController( |
- getContainerView(), mPositionObserver) { |
- @Override |
- public void selectBetweenCoordinates(int x1, int y1, int x2, int y2) { |
- if (mNativeContentViewCore != 0 && !(x1 == x2 && y1 == y2)) { |
- nativeSelectBetweenCoordinates(mNativeContentViewCore, |
- x1, y1 - mRenderCoordinates.getContentOffsetYPix(), |
- x2, y2 - mRenderCoordinates.getContentOffsetYPix()); |
- } |
- } |
- |
- @Override |
- public void showHandles(int startDir, int endDir) { |
- super.showHandles(startDir, endDir); |
- showSelectActionBar(); |
- } |
- |
- }; |
- |
- mSelectionHandleController.hideAndDisallowAutomaticShowing(); |
- } |
- |
- return mSelectionHandleController; |
- } |
- |
- private InsertionHandleController getInsertionHandleController() { |
- if (mInsertionHandleController == null) { |
- mInsertionHandleController = new InsertionHandleController( |
- getContainerView(), mPositionObserver) { |
- private static final int AVERAGE_LINE_HEIGHT = 14; |
- |
- @Override |
- public void setCursorPosition(int x, int y) { |
- if (mNativeContentViewCore != 0) { |
- nativeMoveCaret(mNativeContentViewCore, |
- x, y - mRenderCoordinates.getContentOffsetYPix()); |
- } |
- } |
- |
- @Override |
- public void paste() { |
- mImeAdapter.paste(); |
- hideHandles(); |
- } |
- |
- @Override |
- public int getLineHeight() { |
- return (int) Math.ceil( |
- mRenderCoordinates.fromLocalCssToPix(AVERAGE_LINE_HEIGHT)); |
- } |
- |
- @Override |
- public void showHandle() { |
- super.showHandle(); |
- } |
- }; |
- |
- mInsertionHandleController.hideAndDisallowAutomaticShowing(); |
- } |
- |
- return mInsertionHandleController; |
- } |
- |
- @VisibleForTesting |
- public InsertionHandleController getInsertionHandleControllerForTest() { |
- return mInsertionHandleController; |
- } |
- |
- @VisibleForTesting |
- public SelectionHandleController getSelectionHandleControllerForTest() { |
- return mSelectionHandleController; |
- } |
- |
- private void updateHandleScreenPositions() { |
- if (isSelectionHandleShowing()) { |
- mSelectionHandleController.setStartHandlePosition( |
- mStartHandlePoint.getXPix(), mStartHandlePoint.getYPix()); |
- mSelectionHandleController.setEndHandlePosition( |
- mEndHandlePoint.getXPix(), mEndHandlePoint.getYPix()); |
- } |
- |
- if (isInsertionHandleShowing()) { |
- mInsertionHandleController.setHandlePosition( |
- mInsertionHandlePoint.getXPix(), mInsertionHandlePoint.getYPix()); |
- } |
- } |
- |
- private void hideHandles() { |
- if (mSelectionHandleController != null) { |
- mSelectionHandleController.hideAndDisallowAutomaticShowing(); |
- } |
- if (mInsertionHandleController != null) { |
- mInsertionHandleController.hideAndDisallowAutomaticShowing(); |
- } |
- mPositionObserver.removeListener(mPositionListener); |
- } |
- |
- private void showSelectActionBar() { |
- if (mActionMode != null) { |
- mActionMode.invalidate(); |
- return; |
- } |
- |
- // Start a new action mode with a SelectActionModeCallback. |
- SelectActionModeCallback.ActionHandler actionHandler = |
- new SelectActionModeCallback.ActionHandler() { |
- @Override |
- public void selectAll() { |
- mImeAdapter.selectAll(); |
- } |
- |
- @Override |
- public void cut() { |
- mImeAdapter.cut(); |
- } |
- |
- @Override |
- public void copy() { |
- mImeAdapter.copy(); |
- } |
- |
- @Override |
- public void paste() { |
- mImeAdapter.paste(); |
- } |
- |
- @Override |
- public void share() { |
- final String query = getSelectedText(); |
- if (TextUtils.isEmpty(query)) return; |
- |
- Intent send = new Intent(Intent.ACTION_SEND); |
- send.setType("text/plain"); |
- send.putExtra(Intent.EXTRA_TEXT, query); |
- try { |
- Intent i = Intent.createChooser(send, getContext().getString( |
- R.string.actionbar_share)); |
- i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); |
- getContext().startActivity(i); |
- } catch (android.content.ActivityNotFoundException ex) { |
- // If no app handles it, do nothing. |
- } |
- } |
- |
- @Override |
- public void search() { |
- final String query = getSelectedText(); |
- if (TextUtils.isEmpty(query)) return; |
- |
- // See if ContentViewClient wants to override |
- if (getContentViewClient().doesPerformWebSearch()) { |
- getContentViewClient().performWebSearch(query); |
- return; |
- } |
- |
- Intent i = new Intent(Intent.ACTION_WEB_SEARCH); |
- i.putExtra(SearchManager.EXTRA_NEW_SEARCH, true); |
- i.putExtra(SearchManager.QUERY, query); |
- i.putExtra(Browser.EXTRA_APPLICATION_ID, getContext().getPackageName()); |
- if (!(getContext() instanceof Activity)) { |
- i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); |
- } |
- try { |
- getContext().startActivity(i); |
- } catch (android.content.ActivityNotFoundException ex) { |
- // If no app handles it, do nothing. |
- } |
- } |
- |
- @Override |
- public boolean isSelectionEditable() { |
- return mSelectionEditable; |
- } |
- |
- @Override |
- public void onDestroyActionMode() { |
- mActionMode = null; |
- if (mUnselectAllOnActionModeDismiss) mImeAdapter.unselect(); |
- getContentViewClient().onContextualActionBarHidden(); |
- } |
- |
- @Override |
- public boolean isShareAvailable() { |
- Intent intent = new Intent(Intent.ACTION_SEND); |
- intent.setType("text/plain"); |
- return getContext().getPackageManager().queryIntentActivities(intent, |
- PackageManager.MATCH_DEFAULT_ONLY).size() > 0; |
- } |
- |
- @Override |
- public boolean isWebSearchAvailable() { |
- if (getContentViewClient().doesPerformWebSearch()) return true; |
- Intent intent = new Intent(Intent.ACTION_WEB_SEARCH); |
- intent.putExtra(SearchManager.EXTRA_NEW_SEARCH, true); |
- return getContext().getPackageManager().queryIntentActivities(intent, |
- PackageManager.MATCH_DEFAULT_ONLY).size() > 0; |
- } |
- }; |
- mActionMode = null; |
- // On ICS, startActionMode throws an NPE when getParent() is null. |
- if (mContainerView.getParent() != null) { |
- mActionMode = mContainerView.startActionMode( |
- getContentViewClient().getSelectActionModeCallback(getContext(), actionHandler, |
- nativeIsIncognito(mNativeContentViewCore))); |
- } |
- mUnselectAllOnActionModeDismiss = true; |
- if (mActionMode == null) { |
- // There is no ActionMode, so remove the selection. |
- mImeAdapter.unselect(); |
- } else { |
- getContentViewClient().onContextualActionBarShown(); |
- } |
- } |
- |
- public boolean getUseDesktopUserAgent() { |
- if (mNativeContentViewCore != 0) { |
- return nativeGetUseDesktopUserAgent(mNativeContentViewCore); |
- } |
- return false; |
- } |
- |
- /** |
- * Set whether or not we're using a desktop user agent for the currently loaded page. |
- * @param override If true, use a desktop user agent. Use a mobile one otherwise. |
- * @param reloadOnChange Reload the page if the UA has changed. |
- */ |
- public void setUseDesktopUserAgent(boolean override, boolean reloadOnChange) { |
- if (mNativeContentViewCore != 0) { |
- nativeSetUseDesktopUserAgent(mNativeContentViewCore, override, reloadOnChange); |
- } |
- } |
- |
- public void clearSslPreferences() { |
- nativeClearSslPreferences(mNativeContentViewCore); |
- } |
- |
- private boolean isSelectionHandleShowing() { |
- return mSelectionHandleController != null && mSelectionHandleController.isShowing(); |
- } |
- |
- private boolean isInsertionHandleShowing() { |
- return mInsertionHandleController != null && mInsertionHandleController.isShowing(); |
- } |
- |
- private void updateTextHandlesForGesture(int type) { |
- switch(type) { |
- case ContentViewGestureHandler.GESTURE_DOUBLE_TAP: |
- case ContentViewGestureHandler.GESTURE_SCROLL_START: |
- case ContentViewGestureHandler.GESTURE_FLING_START: |
- case ContentViewGestureHandler.GESTURE_PINCH_BEGIN: |
- temporarilyHideTextHandles(); |
- break; |
- |
- default: |
- break; |
- } |
- } |
- |
- // Makes the insertion/selection handles invisible. They will fade back in shortly after the |
- // last call to scheduleTextHandleFadeIn (or temporarilyHideTextHandles). |
- private void temporarilyHideTextHandles() { |
- if (isSelectionHandleShowing() && !mSelectionHandleController.isDragging()) { |
- mSelectionHandleController.setHandleVisibility(HandleView.INVISIBLE); |
- } |
- if (isInsertionHandleShowing() && !mInsertionHandleController.isDragging()) { |
- mInsertionHandleController.setHandleVisibility(HandleView.INVISIBLE); |
- } |
- scheduleTextHandleFadeIn(); |
- } |
- |
- private boolean allowTextHandleFadeIn() { |
- if (mContentViewGestureHandler.isNativeScrolling() || |
- mContentViewGestureHandler.isNativePinching()) { |
- return false; |
- } |
- |
- if (mPopupZoomer.isShowing()) return false; |
- |
- return true; |
- } |
- |
- // Cancels any pending fade in and schedules a new one. |
- private void scheduleTextHandleFadeIn() { |
- if (!isInsertionHandleShowing() && !isSelectionHandleShowing()) return; |
- |
- if (mDeferredHandleFadeInRunnable == null) { |
- mDeferredHandleFadeInRunnable = new Runnable() { |
- @Override |
- public void run() { |
- if (!allowTextHandleFadeIn()) { |
- // Delay fade in until it is allowed. |
- scheduleTextHandleFadeIn(); |
- } else { |
- if (isSelectionHandleShowing()) { |
- mSelectionHandleController.beginHandleFadeIn(); |
- } |
- if (isInsertionHandleShowing()) { |
- mInsertionHandleController.beginHandleFadeIn(); |
- } |
- } |
- } |
- }; |
- } |
- |
- mContainerView.removeCallbacks(mDeferredHandleFadeInRunnable); |
- mContainerView.postDelayed(mDeferredHandleFadeInRunnable, TEXT_HANDLE_FADE_IN_DELAY); |
- } |
- |
- /** |
- * Shows the IME if the focused widget could accept text input. |
- */ |
- public void showImeIfNeeded() { |
- if (mNativeContentViewCore != 0) nativeShowImeIfNeeded(mNativeContentViewCore); |
- } |
- |
- @SuppressWarnings("unused") |
- @CalledByNative |
- private void updateFrameInfo( |
- float scrollOffsetX, float scrollOffsetY, |
- float pageScaleFactor, float minPageScaleFactor, float maxPageScaleFactor, |
- float contentWidth, float contentHeight, |
- float viewportWidth, float viewportHeight, |
- float controlsOffsetYCss, float contentOffsetYCss, |
- float overdrawBottomHeightCss) { |
- TraceEvent.instant("ContentViewCore:updateFrameInfo"); |
- // Adjust contentWidth/Height to be always at least as big as |
- // the actual viewport (as set by onSizeChanged). |
- contentWidth = Math.max(contentWidth, |
- mRenderCoordinates.fromPixToLocalCss(mViewportWidthPix)); |
- contentHeight = Math.max(contentHeight, |
- mRenderCoordinates.fromPixToLocalCss(mViewportHeightPix)); |
- |
- final float contentOffsetYPix = mRenderCoordinates.fromDipToPix(contentOffsetYCss); |
- |
- final boolean contentSizeChanged = |
- contentWidth != mRenderCoordinates.getContentWidthCss() |
- || contentHeight != mRenderCoordinates.getContentHeightCss(); |
- final boolean scaleLimitsChanged = |
- minPageScaleFactor != mRenderCoordinates.getMinPageScaleFactor() |
- || maxPageScaleFactor != mRenderCoordinates.getMaxPageScaleFactor(); |
- final boolean pageScaleChanged = |
- pageScaleFactor != mRenderCoordinates.getPageScaleFactor(); |
- final boolean scrollChanged = |
- pageScaleChanged |
- || scrollOffsetX != mRenderCoordinates.getScrollX() |
- || scrollOffsetY != mRenderCoordinates.getScrollY(); |
- final boolean contentOffsetChanged = |
- contentOffsetYPix != mRenderCoordinates.getContentOffsetYPix(); |
- |
- final boolean needHidePopupZoomer = contentSizeChanged || scrollChanged; |
- final boolean needUpdateZoomControls = scaleLimitsChanged || scrollChanged; |
- final boolean needTemporarilyHideHandles = scrollChanged; |
- |
- if (needHidePopupZoomer) mPopupZoomer.hide(true); |
- |
- if (scrollChanged) { |
- mContainerViewInternals.onScrollChanged( |
- (int) mRenderCoordinates.fromLocalCssToPix(scrollOffsetX), |
- (int) mRenderCoordinates.fromLocalCssToPix(scrollOffsetY), |
- (int) mRenderCoordinates.getScrollXPix(), |
- (int) mRenderCoordinates.getScrollYPix()); |
- } |
- |
- mRenderCoordinates.updateFrameInfo( |
- scrollOffsetX, scrollOffsetY, |
- contentWidth, contentHeight, |
- viewportWidth, viewportHeight, |
- pageScaleFactor, minPageScaleFactor, maxPageScaleFactor, |
- contentOffsetYPix); |
- onRenderCoordinatesUpdated(); |
- |
- if (needTemporarilyHideHandles) temporarilyHideTextHandles(); |
- if (needUpdateZoomControls) mZoomControlsDelegate.updateZoomControls(); |
- if (contentOffsetChanged) updateHandleScreenPositions(); |
- |
- // Update offsets for fullscreen. |
- final float deviceScale = mRenderCoordinates.getDeviceScaleFactor(); |
- final float controlsOffsetPix = controlsOffsetYCss * deviceScale; |
- final float overdrawBottomHeightPix = overdrawBottomHeightCss * deviceScale; |
- getContentViewClient().onOffsetsForFullscreenChanged( |
- controlsOffsetPix, contentOffsetYPix, overdrawBottomHeightPix); |
- |
- mPendingRendererFrame = true; |
- if (mBrowserAccessibilityManager != null) { |
- mBrowserAccessibilityManager.notifyFrameInfoInitialized(); |
- } |
- |
- // Update geometry for external video surface. |
- getContentViewClient().onGeometryChanged(-1, null); |
- } |
- |
- @CalledByNative |
- private void updateImeAdapter(int nativeImeAdapterAndroid, int textInputType, |
- String text, int selectionStart, int selectionEnd, |
- int compositionStart, int compositionEnd, boolean showImeIfNeeded, boolean requireAck) { |
- TraceEvent.begin(); |
- mSelectionEditable = (textInputType != ImeAdapter.getTextInputTypeNone()); |
- |
- if (mActionMode != null) mActionMode.invalidate(); |
- |
- mImeAdapter.attachAndShowIfNeeded(nativeImeAdapterAndroid, textInputType, |
- selectionStart, selectionEnd, showImeIfNeeded); |
- |
- if (mInputConnection != null) { |
- mInputConnection.updateState(text, selectionStart, selectionEnd, compositionStart, |
- compositionEnd, requireAck); |
- } |
- TraceEvent.end(); |
- } |
- |
- @SuppressWarnings("unused") |
- @CalledByNative |
- private void setTitle(String title) { |
- getContentViewClient().onUpdateTitle(title); |
- } |
- |
- /** |
- * Called (from native) when the <select> popup needs to be shown. |
- * @param items Items to show. |
- * @param enabled POPUP_ITEM_TYPEs for items. |
- * @param multiple Whether the popup menu should support multi-select. |
- * @param selectedIndices Indices of selected items. |
- */ |
- @SuppressWarnings("unused") |
- @CalledByNative |
- private void showSelectPopup(String[] items, int[] enabled, boolean multiple, |
- int[] selectedIndices) { |
- assert items.length == enabled.length; |
- List<SelectPopupItem> popupItems = new ArrayList<SelectPopupItem>(); |
- for (int i = 0; i < items.length; i++) { |
- popupItems.add(new SelectPopupItem(items[i], enabled[i])); |
- } |
- SelectPopupDialog.show(this, popupItems, multiple, selectedIndices); |
- } |
- |
- @SuppressWarnings("unused") |
- @CalledByNative |
- private void showDisambiguationPopup(Rect targetRect, Bitmap zoomedBitmap) { |
- mPopupZoomer.setBitmap(zoomedBitmap); |
- mPopupZoomer.show(targetRect); |
- temporarilyHideTextHandles(); |
- } |
- |
- @SuppressWarnings("unused") |
- @CalledByNative |
- private TouchEventSynthesizer createTouchEventSynthesizer() { |
- return new TouchEventSynthesizer(this); |
- } |
- |
- @SuppressWarnings("unused") |
- @CalledByNative |
- private void onSelectionChanged(String text) { |
- mLastSelectedText = text; |
- } |
- |
- @SuppressWarnings("unused") |
- @CalledByNative |
- private void onSelectionBoundsChanged(Rect anchorRectDip, int anchorDir, Rect focusRectDip, |
- int focusDir, boolean isAnchorFirst) { |
- // All coordinates are in DIP. |
- int x1 = anchorRectDip.left; |
- int y1 = anchorRectDip.bottom; |
- int x2 = focusRectDip.left; |
- int y2 = focusRectDip.bottom; |
- |
- if (x1 != x2 || y1 != y2 || |
- (mSelectionHandleController != null && mSelectionHandleController.isDragging())) { |
- if (mInsertionHandleController != null) { |
- mInsertionHandleController.hide(); |
- } |
- if (isAnchorFirst) { |
- mStartHandlePoint.setLocalDip(x1, y1); |
- mEndHandlePoint.setLocalDip(x2, y2); |
- } else { |
- mStartHandlePoint.setLocalDip(x2, y2); |
- mEndHandlePoint.setLocalDip(x1, y1); |
- } |
- |
- boolean wereSelectionHandlesShowing = getSelectionHandleController().isShowing(); |
- |
- getSelectionHandleController().onSelectionChanged(anchorDir, focusDir); |
- updateHandleScreenPositions(); |
- mHasSelection = true; |
- |
- if (!wereSelectionHandlesShowing && getSelectionHandleController().isShowing()) { |
- // TODO(cjhopman): Remove this when there is a better signal that long press caused |
- // a selection. See http://crbug.com/150151. |
- mContainerView.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS); |
- } |
- |
- } else { |
- mUnselectAllOnActionModeDismiss = false; |
- hideSelectActionBar(); |
- if (x1 != 0 && y1 != 0 && mSelectionEditable) { |
- // Selection is a caret, and a text field is focused. |
- if (mSelectionHandleController != null) { |
- mSelectionHandleController.hide(); |
- } |
- mInsertionHandlePoint.setLocalDip(x1, y1); |
- |
- getInsertionHandleController().onCursorPositionChanged(); |
- updateHandleScreenPositions(); |
- InputMethodManager manager = (InputMethodManager) |
- getContext().getSystemService(Context.INPUT_METHOD_SERVICE); |
- if (manager.isWatchingCursor(mContainerView)) { |
- final int xPix = (int) mInsertionHandlePoint.getXPix(); |
- final int yPix = (int) mInsertionHandlePoint.getYPix(); |
- manager.updateCursor(mContainerView, xPix, yPix, xPix, yPix); |
- } |
- } else { |
- // Deselection |
- if (mSelectionHandleController != null) { |
- mSelectionHandleController.hideAndDisallowAutomaticShowing(); |
- } |
- if (mInsertionHandleController != null) { |
- mInsertionHandleController.hideAndDisallowAutomaticShowing(); |
- } |
- } |
- mHasSelection = false; |
- } |
- if (isSelectionHandleShowing() || isInsertionHandleShowing()) { |
- mPositionObserver.addListener(mPositionListener); |
- } |
- } |
- |
- @SuppressWarnings("unused") |
- @CalledByNative |
- private static void onEvaluateJavaScriptResult( |
- String jsonResult, JavaScriptCallback callback) { |
- callback.handleJavaScriptResult(jsonResult); |
- } |
- |
- @SuppressWarnings("unused") |
- @CalledByNative |
- private void showPastePopup(int xDip, int yDip) { |
- mInsertionHandlePoint.setLocalDip(xDip, yDip); |
- getInsertionHandleController().showHandle(); |
- updateHandleScreenPositions(); |
- getInsertionHandleController().showHandleWithPastePopup(); |
- } |
- |
- @SuppressWarnings("unused") |
- @CalledByNative |
- private void onRenderProcessSwap(int oldPid, int newPid) { |
- if (!mInForeground) { |
- ChildProcessLauncher.getBindingManager().setInForeground(newPid, false); |
- } else if (oldPid != newPid) { |
- ChildProcessLauncher.getBindingManager().setInForeground(oldPid, false); |
- ChildProcessLauncher.getBindingManager().setInForeground(newPid, true); |
- } |
- |
- attachImeAdapter(); |
- } |
- |
- @SuppressWarnings("unused") |
- @CalledByNative |
- private void onWebContentsConnected() { |
- attachImeAdapter(); |
- } |
- |
- /** |
- * Attaches the native ImeAdapter object to the java ImeAdapter to allow communication via JNI. |
- */ |
- public void attachImeAdapter() { |
- if (mImeAdapter != null && mNativeContentViewCore != 0) { |
- mImeAdapter.attach(nativeGetNativeImeAdapter(mNativeContentViewCore)); |
- } |
- } |
- |
- /** |
- * @see View#hasFocus() |
- */ |
- @CalledByNative |
- public boolean hasFocus() { |
- return mContainerView.hasFocus(); |
- } |
- |
- /** |
- * Checks whether the ContentViewCore can be zoomed in. |
- * |
- * @return True if the ContentViewCore can be zoomed in. |
- */ |
- // This method uses the term 'zoom' for legacy reasons, but relates |
- // to what chrome calls the 'page scale factor'. |
- public boolean canZoomIn() { |
- final float zoomInExtent = mRenderCoordinates.getMaxPageScaleFactor() |
- - mRenderCoordinates.getPageScaleFactor(); |
- return zoomInExtent > ZOOM_CONTROLS_EPSILON; |
- } |
- |
- /** |
- * Checks whether the ContentViewCore can be zoomed out. |
- * |
- * @return True if the ContentViewCore can be zoomed out. |
- */ |
- // This method uses the term 'zoom' for legacy reasons, but relates |
- // to what chrome calls the 'page scale factor'. |
- public boolean canZoomOut() { |
- final float zoomOutExtent = mRenderCoordinates.getPageScaleFactor() |
- - mRenderCoordinates.getMinPageScaleFactor(); |
- return zoomOutExtent > ZOOM_CONTROLS_EPSILON; |
- } |
- |
- /** |
- * Zooms in the ContentViewCore by 25% (or less if that would result in |
- * zooming in more than possible). |
- * |
- * @return True if there was a zoom change, false otherwise. |
- */ |
- // This method uses the term 'zoom' for legacy reasons, but relates |
- // to what chrome calls the 'page scale factor'. |
- public boolean zoomIn() { |
- if (!canZoomIn()) { |
- return false; |
- } |
- return pinchByDelta(1.25f); |
- } |
- |
- /** |
- * Zooms out the ContentViewCore by 20% (or less if that would result in |
- * zooming out more than possible). |
- * |
- * @return True if there was a zoom change, false otherwise. |
- */ |
- // This method uses the term 'zoom' for legacy reasons, but relates |
- // to what chrome calls the 'page scale factor'. |
- public boolean zoomOut() { |
- if (!canZoomOut()) { |
- return false; |
- } |
- return pinchByDelta(0.8f); |
- } |
- |
- /** |
- * Resets the zoom factor of the ContentViewCore. |
- * |
- * @return True if there was a zoom change, false otherwise. |
- */ |
- // This method uses the term 'zoom' for legacy reasons, but relates |
- // to what chrome calls the 'page scale factor'. |
- public boolean zoomReset() { |
- // The page scale factor is initialized to mNativeMinimumScale when |
- // the page finishes loading. Thus sets it back to mNativeMinimumScale. |
- if (!canZoomOut()) return false; |
- return pinchByDelta( |
- mRenderCoordinates.getMinPageScaleFactor() |
- / mRenderCoordinates.getPageScaleFactor()); |
- } |
- |
- /** |
- * Simulate a pinch zoom gesture. |
- * |
- * @param delta the factor by which the current page scale should be multiplied by. |
- * @return whether the gesture was sent. |
- */ |
- public boolean pinchByDelta(float delta) { |
- if (mNativeContentViewCore == 0) { |
- return false; |
- } |
- |
- long timeMs = System.currentTimeMillis(); |
- int xPix = getViewportWidthPix() / 2; |
- int yPix = getViewportHeightPix() / 2; |
- |
- getContentViewGestureHandler().pinchBegin(timeMs, xPix, yPix); |
- getContentViewGestureHandler().pinchBy(timeMs, xPix, yPix, delta); |
- getContentViewGestureHandler().pinchEnd(timeMs); |
- |
- return true; |
- } |
- |
- /** |
- * Invokes the graphical zoom picker widget for this ContentView. |
- */ |
- @Override |
- public void invokeZoomPicker() { |
- mZoomControlsDelegate.invokeZoomPicker(); |
- } |
- |
- /** |
- * This will mimic {@link #addPossiblyUnsafeJavascriptInterface(Object, String, Class)} |
- * and automatically pass in {@link JavascriptInterface} as the required annotation. |
- * |
- * @param object The Java object to inject into the ContentViewCore's JavaScript context. Null |
- * values are ignored. |
- * @param name The name used to expose the instance in JavaScript. |
- */ |
- public void addJavascriptInterface(Object object, String name) { |
- addPossiblyUnsafeJavascriptInterface(object, name, JavascriptInterface.class); |
- } |
- |
- /** |
- * This method injects the supplied Java object into the ContentViewCore. |
- * The object is injected into the JavaScript context of the main frame, |
- * using the supplied name. This allows the Java object to be accessed from |
- * JavaScript. Note that that injected objects will not appear in |
- * JavaScript until the page is next (re)loaded. For example: |
- * <pre> view.addJavascriptInterface(new Object(), "injectedObject"); |
- * view.loadData("<!DOCTYPE html><title></title>", "text/html", null); |
- * view.loadUrl("javascript:alert(injectedObject.toString())");</pre> |
- * <p><strong>IMPORTANT:</strong> |
- * <ul> |
- * <li> addJavascriptInterface() can be used to allow JavaScript to control |
- * the host application. This is a powerful feature, but also presents a |
- * security risk. Use of this method in a ContentViewCore containing |
- * untrusted content could allow an attacker to manipulate the host |
- * application in unintended ways, executing Java code with the permissions |
- * of the host application. Use extreme care when using this method in a |
- * ContentViewCore which could contain untrusted content. Particular care |
- * should be taken to avoid unintentional access to inherited methods, such |
- * as {@link Object#getClass()}. To prevent access to inherited methods, |
- * pass an annotation for {@code requiredAnnotation}. This will ensure |
- * that only methods with {@code requiredAnnotation} are exposed to the |
- * Javascript layer. {@code requiredAnnotation} will be passed to all |
- * subsequently injected Java objects if any methods return an object. This |
- * means the same restrictions (or lack thereof) will apply. Alternatively, |
- * {@link #addJavascriptInterface(Object, String)} can be called, which |
- * automatically uses the {@link JavascriptInterface} annotation. |
- * <li> JavaScript interacts with Java objects on a private, background |
- * thread of the ContentViewCore. Care is therefore required to maintain |
- * thread safety.</li> |
- * </ul></p> |
- * |
- * @param object The Java object to inject into the |
- * ContentViewCore's JavaScript context. Null |
- * values are ignored. |
- * @param name The name used to expose the instance in |
- * JavaScript. |
- * @param requiredAnnotation Restrict exposed methods to ones with this |
- * annotation. If {@code null} all methods are |
- * exposed. |
- * |
- */ |
- public void addPossiblyUnsafeJavascriptInterface(Object object, String name, |
- Class<? extends Annotation> requiredAnnotation) { |
- if (mNativeContentViewCore != 0 && object != null) { |
- mJavaScriptInterfaces.put(name, object); |
- nativeAddJavascriptInterface(mNativeContentViewCore, object, name, requiredAnnotation, |
- mRetainedJavaScriptObjects); |
- } |
- } |
- |
- /** |
- * Removes a previously added JavaScript interface with the given name. |
- * |
- * @param name The name of the interface to remove. |
- */ |
- public void removeJavascriptInterface(String name) { |
- mJavaScriptInterfaces.remove(name); |
- if (mNativeContentViewCore != 0) { |
- nativeRemoveJavascriptInterface(mNativeContentViewCore, name); |
- } |
- } |
- |
- /** |
- * Return the current scale of the ContentView. |
- * @return The current page scale factor. |
- */ |
- public float getScale() { |
- return mRenderCoordinates.getPageScaleFactor(); |
- } |
- |
- /** |
- * If the view is ready to draw contents to the screen. In hardware mode, |
- * the initialization of the surface texture may not occur until after the |
- * view has been added to the layout. This method will return {@code true} |
- * once the texture is actually ready. |
- */ |
- public boolean isReady() { |
- if (mNativeContentViewCore == 0) return false; |
- return nativeIsRenderWidgetHostViewReady(mNativeContentViewCore); |
- } |
- |
- @CalledByNative |
- private void startContentIntent(String contentUrl) { |
- getContentViewClient().onStartContentIntent(getContext(), contentUrl); |
- } |
- |
- @Override |
- public void onAccessibilityStateChanged(boolean enabled) { |
- setAccessibilityState(enabled); |
- } |
- |
- /** |
- * Determines whether or not this ContentViewCore can handle this accessibility action. |
- * @param action The action to perform. |
- * @return Whether or not this action is supported. |
- */ |
- public boolean supportsAccessibilityAction(int action) { |
- return mAccessibilityInjector.supportsAccessibilityAction(action); |
- } |
- |
- /** |
- * Attempts to perform an accessibility action on the web content. If the accessibility action |
- * cannot be processed, it returns {@code null}, allowing the caller to know to call the |
- * super {@link View#performAccessibilityAction(int, Bundle)} method and use that return value. |
- * Otherwise the return value from this method should be used. |
- * @param action The action to perform. |
- * @param arguments Optional action arguments. |
- * @return Whether the action was performed or {@code null} if the call should be delegated to |
- * the super {@link View} class. |
- */ |
- public boolean performAccessibilityAction(int action, Bundle arguments) { |
- if (mAccessibilityInjector.supportsAccessibilityAction(action)) { |
- return mAccessibilityInjector.performAccessibilityAction(action, arguments); |
- } |
- |
- return false; |
- } |
- |
- /** |
- * Set the BrowserAccessibilityManager, used for native accessibility |
- * (not script injection). This is only set when system accessibility |
- * has been enabled. |
- * @param manager The new BrowserAccessibilityManager. |
- */ |
- public void setBrowserAccessibilityManager(BrowserAccessibilityManager manager) { |
- mBrowserAccessibilityManager = manager; |
- } |
- |
- /** |
- * Get the BrowserAccessibilityManager, used for native accessibility |
- * (not script injection). This will return null when system accessibility |
- * is not enabled. |
- * @return This view's BrowserAccessibilityManager. |
- */ |
- public BrowserAccessibilityManager getBrowserAccessibilityManager() { |
- return mBrowserAccessibilityManager; |
- } |
- |
- /** |
- * If native accessibility (not script injection) is enabled, and if this is |
- * running on JellyBean or later, returns an AccessibilityNodeProvider that |
- * implements native accessibility for this view. Returns null otherwise. |
- * Lazily initializes native accessibility here if it's allowed. |
- * @return The AccessibilityNodeProvider, if available, or null otherwise. |
- */ |
- public AccessibilityNodeProvider getAccessibilityNodeProvider() { |
- if (mBrowserAccessibilityManager != null) { |
- return mBrowserAccessibilityManager.getAccessibilityNodeProvider(); |
- } |
- |
- if (mNativeAccessibilityAllowed && |
- !mNativeAccessibilityEnabled && |
- mNativeContentViewCore != 0 && |
- Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { |
- mNativeAccessibilityEnabled = true; |
- nativeSetAccessibilityEnabled(mNativeContentViewCore, true); |
- } |
- |
- return null; |
- } |
- |
- /** |
- * @see View#onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo) |
- */ |
- public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) { |
- // Note: this is only used by the script-injecting accessibility code. |
- mAccessibilityInjector.onInitializeAccessibilityNodeInfo(info); |
- } |
- |
- /** |
- * @see View#onInitializeAccessibilityEvent(AccessibilityEvent) |
- */ |
- public void onInitializeAccessibilityEvent(AccessibilityEvent event) { |
- // Note: this is only used by the script-injecting accessibility code. |
- event.setClassName(this.getClass().getName()); |
- |
- // Identify where the top-left of the screen currently points to. |
- event.setScrollX(mRenderCoordinates.getScrollXPixInt()); |
- event.setScrollY(mRenderCoordinates.getScrollYPixInt()); |
- |
- // The maximum scroll values are determined by taking the content dimensions and |
- // subtracting off the actual dimensions of the ChromeView. |
- int maxScrollXPix = Math.max(0, mRenderCoordinates.getMaxHorizontalScrollPixInt()); |
- int maxScrollYPix = Math.max(0, mRenderCoordinates.getMaxVerticalScrollPixInt()); |
- event.setScrollable(maxScrollXPix > 0 || maxScrollYPix > 0); |
- |
- // Setting the maximum scroll values requires API level 15 or higher. |
- final int SDK_VERSION_REQUIRED_TO_SET_SCROLL = 15; |
- if (Build.VERSION.SDK_INT >= SDK_VERSION_REQUIRED_TO_SET_SCROLL) { |
- event.setMaxScrollX(maxScrollXPix); |
- event.setMaxScrollY(maxScrollYPix); |
- } |
- } |
- |
- /** |
- * Returns whether accessibility script injection is enabled on the device |
- */ |
- public boolean isDeviceAccessibilityScriptInjectionEnabled() { |
- try { |
- if (CommandLine.getInstance().hasSwitch( |
- ContentSwitches.DISABLE_ACCESSIBILITY_SCRIPT_INJECTION)) { |
- return false; |
- } |
- |
- if (!mContentSettings.getJavaScriptEnabled()) { |
- return false; |
- } |
- |
- int result = getContext().checkCallingOrSelfPermission( |
- android.Manifest.permission.INTERNET); |
- if (result != PackageManager.PERMISSION_GRANTED) { |
- return false; |
- } |
- |
- Field field = Settings.Secure.class.getField("ACCESSIBILITY_SCRIPT_INJECTION"); |
- field.setAccessible(true); |
- String accessibilityScriptInjection = (String) field.get(null); |
- ContentResolver contentResolver = getContext().getContentResolver(); |
- |
- if (mAccessibilityScriptInjectionObserver == null) { |
- ContentObserver contentObserver = new ContentObserver(new Handler()) { |
- @Override |
- public void onChange(boolean selfChange, Uri uri) { |
- setAccessibilityState(mAccessibilityManager.isEnabled()); |
- } |
- }; |
- contentResolver.registerContentObserver( |
- Settings.Secure.getUriFor(accessibilityScriptInjection), |
- false, |
- contentObserver); |
- mAccessibilityScriptInjectionObserver = contentObserver; |
- } |
- |
- return Settings.Secure.getInt(contentResolver, accessibilityScriptInjection, 0) == 1; |
- } catch (NoSuchFieldException e) { |
- // Do nothing, default to false. |
- } catch (IllegalAccessException e) { |
- // Do nothing, default to false. |
- } |
- return false; |
- } |
- |
- /** |
- * Returns whether or not accessibility injection is being used. |
- */ |
- public boolean isInjectingAccessibilityScript() { |
- return mAccessibilityInjector.accessibilityIsAvailable(); |
- } |
- |
- /** |
- * Turns browser accessibility on or off. |
- * If |state| is |false|, this turns off both native and injected accessibility. |
- * Otherwise, if accessibility script injection is enabled, this will enable the injected |
- * accessibility scripts. Native accessibility is enabled on demand. |
- */ |
- public void setAccessibilityState(boolean state) { |
- if (!state) { |
- setInjectedAccessibility(false); |
- mNativeAccessibilityAllowed = false; |
- } else { |
- boolean useScriptInjection = isDeviceAccessibilityScriptInjectionEnabled(); |
- setInjectedAccessibility(useScriptInjection); |
- mNativeAccessibilityAllowed = !useScriptInjection; |
- } |
- } |
- |
- /** |
- * Enable or disable injected accessibility features |
- */ |
- public void setInjectedAccessibility(boolean enabled) { |
- mAccessibilityInjector.addOrRemoveAccessibilityApisIfNecessary(); |
- mAccessibilityInjector.setScriptEnabled(enabled); |
- } |
- |
- /** |
- * Stop any TTS notifications that are currently going on. |
- */ |
- public void stopCurrentAccessibilityNotifications() { |
- mAccessibilityInjector.onPageLostFocus(); |
- } |
- |
- /** |
- * Inform WebKit that Fullscreen mode has been exited by the user. |
- */ |
- public void exitFullscreen() { |
- if (mNativeContentViewCore != 0) nativeExitFullscreen(mNativeContentViewCore); |
- } |
- |
- /** |
- * Changes whether hiding the top controls is enabled. |
- * |
- * @param enableHiding Whether hiding the top controls should be enabled or not. |
- * @param enableShowing Whether showing the top controls should be enabled or not. |
- * @param animate Whether the transition should be animated or not. |
- */ |
- public void updateTopControlsState(boolean enableHiding, boolean enableShowing, |
- boolean animate) { |
- if (mNativeContentViewCore != 0) { |
- nativeUpdateTopControlsState( |
- mNativeContentViewCore, enableHiding, enableShowing, animate); |
- } |
- } |
- |
- /** |
- * Callback factory method for nativeGetNavigationHistory(). |
- */ |
- @CalledByNative |
- private void addToNavigationHistory(Object history, int index, String url, String virtualUrl, |
- String originalUrl, String title, Bitmap favicon) { |
- NavigationEntry entry = new NavigationEntry( |
- index, url, virtualUrl, originalUrl, title, favicon); |
- ((NavigationHistory) history).addEntry(entry); |
- } |
- |
- /** |
- * Get a copy of the navigation history of the view. |
- */ |
- public NavigationHistory getNavigationHistory() { |
- NavigationHistory history = new NavigationHistory(); |
- if (mNativeContentViewCore != 0) { |
- int currentIndex = nativeGetNavigationHistory(mNativeContentViewCore, history); |
- history.setCurrentEntryIndex(currentIndex); |
- } |
- return history; |
- } |
- |
- @Override |
- public NavigationHistory getDirectedNavigationHistory(boolean isForward, int itemLimit) { |
- NavigationHistory history = new NavigationHistory(); |
- if (mNativeContentViewCore != 0) { |
- nativeGetDirectedNavigationHistory( |
- mNativeContentViewCore, history, isForward, itemLimit); |
- } |
- return history; |
- } |
- |
- /** |
- * @return The original request URL for the current navigation entry, or null if there is no |
- * current entry. |
- */ |
- public String getOriginalUrlForActiveNavigationEntry() { |
- if (mNativeContentViewCore != 0) { |
- return nativeGetOriginalUrlForActiveNavigationEntry(mNativeContentViewCore); |
- } |
- return ""; |
- } |
- |
- /** |
- * @return The cached copy of render positions and scales. |
- */ |
- public RenderCoordinates getRenderCoordinates() { |
- return mRenderCoordinates; |
- } |
- |
- @CalledByNative |
- private int getLocationInWindowX() { |
- return mLocationInWindowX; |
- } |
- |
- @CalledByNative |
- private int getLocationInWindowY() { |
- return mLocationInWindowY; |
- } |
- |
- @CalledByNative |
- private static Rect createRect(int x, int y, int right, int bottom) { |
- return new Rect(x, y, right, bottom); |
- } |
- |
- public void attachExternalVideoSurface(int playerId, Surface surface) { |
- if (mNativeContentViewCore != 0) { |
- nativeAttachExternalVideoSurface(mNativeContentViewCore, playerId, surface); |
- } |
- } |
- |
- public void detachExternalVideoSurface(int playerId) { |
- if (mNativeContentViewCore != 0) { |
- nativeDetachExternalVideoSurface(mNativeContentViewCore, playerId); |
- } |
- } |
- |
- private boolean onAnimate(long frameTimeMicros) { |
- if (mNativeContentViewCore == 0) return false; |
- return nativeOnAnimate(mNativeContentViewCore, frameTimeMicros); |
- } |
- |
- private void animateIfNecessary(long frameTimeMicros) { |
- if (mNeedAnimate) { |
- mNeedAnimate = onAnimate(frameTimeMicros); |
- if (!mNeedAnimate) removeVSyncSubscriber(); |
- } |
- } |
- |
- @CalledByNative |
- private void notifyExternalSurface( |
- int playerId, boolean isRequest, float x, float y, float width, float height) { |
- if (isRequest) getContentViewClient().onExternalVideoSurfaceRequested(playerId); |
- getContentViewClient().onGeometryChanged(playerId, new RectF(x, y, x + width, y + height)); |
- } |
- |
- public void extractSmartClipData(int x, int y, int width, int height) { |
- if (mNativeContentViewCore != 0) { |
- nativeExtractSmartClipData(mNativeContentViewCore, x, y, width, height); |
- } |
- } |
- |
- @CalledByNative |
- private void onSmartClipDataExtracted(String result) { |
- if (mSmartClipDataListener != null ) { |
- mSmartClipDataListener.onSmartClipDataExtracted(result); |
- } |
- } |
- |
- public void setSmartClipDataListener(SmartClipDataListener listener) { |
- mSmartClipDataListener = listener; |
- } |
- |
- /** |
- * Offer a subset of gesture events to the embedding View, |
- * primarily for WebView compatibility. |
- * |
- * @param type The type of the event. |
- * |
- * @return true if the embedder handled the event. |
- */ |
- private boolean offerGestureToEmbedder(int type) { |
- if (type == ContentViewGestureHandler.GESTURE_LONG_PRESS) { |
- return mContainerView.performLongClick(); |
- } |
- return false; |
- } |
- |
- private native long nativeInit(boolean hardwareAccelerated, long webContentsPtr, |
- long viewAndroidPtr, long windowAndroidPtr); |
- |
- @CalledByNative |
- private ContentVideoViewClient getContentVideoViewClient() { |
- return getContentViewClient().getContentVideoViewClient(); |
- } |
- |
- @CalledByNative |
- private boolean shouldBlockMediaRequest(String url) { |
- return getContentViewClient().shouldBlockMediaRequest(url); |
- } |
- |
- @CalledByNative |
- private void onNativeFlingStopped() { |
- getContentViewClient().onFlingStopped(); |
- } |
- |
- private native WebContents nativeGetWebContentsAndroid(long nativeContentViewCoreImpl); |
- |
- private native void nativeOnJavaContentViewCoreDestroyed(long nativeContentViewCoreImpl); |
- |
- private native void nativeLoadUrl( |
- long nativeContentViewCoreImpl, |
- String url, |
- int loadUrlType, |
- int transitionType, |
- int uaOverrideOption, |
- String extraHeaders, |
- byte[] postData, |
- String baseUrlForDataUrl, |
- String virtualUrlForDataUrl, |
- boolean canLoadLocalResources); |
- |
- private native String nativeGetURL(long nativeContentViewCoreImpl); |
- |
- private native String nativeGetTitle(long nativeContentViewCoreImpl); |
- |
- private native void nativeShowInterstitialPage( |
- long nativeContentViewCoreImpl, String url, long nativeInterstitialPageDelegateAndroid); |
- private native boolean nativeIsShowingInterstitialPage(long nativeContentViewCoreImpl); |
- |
- private native boolean nativeIsIncognito(long nativeContentViewCoreImpl); |
- |
- private native void nativeSetFocus(long nativeContentViewCoreImpl, boolean focused); |
- |
- private native void nativeSendOrientationChangeEvent( |
- long nativeContentViewCoreImpl, int orientation); |
- |
- // All touch events (including flings, scrolls etc) accept coordinates in physical pixels. |
- private native boolean nativeSendTouchEvent( |
- long nativeContentViewCoreImpl, long timeMs, int action, TouchPoint[] pts); |
- |
- private native int nativeSendMouseMoveEvent( |
- long nativeContentViewCoreImpl, long timeMs, float x, float y); |
- |
- private native int nativeSendMouseWheelEvent( |
- long nativeContentViewCoreImpl, long timeMs, float x, float y, float verticalAxis); |
- |
- private native void nativeScrollBegin( |
- long nativeContentViewCoreImpl, long timeMs, float x, float y, float hintX, |
- float hintY); |
- |
- private native void nativeScrollEnd(long nativeContentViewCoreImpl, long timeMs); |
- |
- private native void nativeScrollBy( |
- long nativeContentViewCoreImpl, long timeMs, float x, float y, |
- float deltaX, float deltaY); |
- |
- private native void nativeFlingStart( |
- long nativeContentViewCoreImpl, long timeMs, float x, float y, float vx, float vy); |
- |
- private native void nativeFlingCancel(long nativeContentViewCoreImpl, long timeMs); |
- |
- private native void nativeSingleTap( |
- long nativeContentViewCoreImpl, long timeMs, float x, float y, boolean linkPreviewTap); |
- |
- private native void nativeSingleTapUnconfirmed( |
- long nativeContentViewCoreImpl, long timeMs, float x, float y); |
- |
- private native void nativeShowPressState( |
- long nativeContentViewCoreImpl, long timeMs, float x, float y); |
- |
- private native void nativeTapCancel( |
- long nativeContentViewCoreImpl, long timeMs, float x, float y); |
- |
- private native void nativeTapDown( |
- long nativeContentViewCoreImpl, long timeMs, float x, float y); |
- |
- private native void nativeDoubleTap( |
- long nativeContentViewCoreImpl, long timeMs, float x, float y); |
- |
- private native void nativeLongPress( |
- long nativeContentViewCoreImpl, long timeMs, float x, float y, boolean linkPreviewTap); |
- |
- private native void nativeLongTap( |
- long nativeContentViewCoreImpl, long timeMs, float x, float y, boolean linkPreviewTap); |
- |
- private native void nativePinchBegin( |
- long nativeContentViewCoreImpl, long timeMs, float x, float y); |
- |
- private native void nativePinchEnd(long nativeContentViewCoreImpl, long timeMs); |
- |
- private native void nativePinchBy(long nativeContentViewCoreImpl, long timeMs, |
- float anchorX, float anchorY, float deltaScale); |
- |
- private native void nativeSelectBetweenCoordinates( |
- long nativeContentViewCoreImpl, float x1, float y1, float x2, float y2); |
- |
- private native void nativeMoveCaret(long nativeContentViewCoreImpl, float x, float y); |
- |
- private native void nativeLoadIfNecessary(long nativeContentViewCoreImpl); |
- private native void nativeRequestRestoreLoad(long nativeContentViewCoreImpl); |
- |
- private native void nativeStopLoading(long nativeContentViewCoreImpl); |
- |
- private native void nativeReload(long nativeContentViewCoreImpl, boolean checkForRepost); |
- private native void nativeReloadIgnoringCache( |
- long nativeContentViewCoreImpl, boolean checkForRepost); |
- |
- private native void nativeCancelPendingReload(long nativeContentViewCoreImpl); |
- |
- private native void nativeContinuePendingReload(long nativeContentViewCoreImpl); |
- |
- private native void nativeSelectPopupMenuItems(long nativeContentViewCoreImpl, int[] indices); |
- |
- private native void nativeScrollFocusedEditableNodeIntoView(long nativeContentViewCoreImpl); |
- private native void nativeUndoScrollFocusedEditableNodeIntoView(long nativeContentViewCoreImpl); |
- |
- private native void nativeClearHistory(long nativeContentViewCoreImpl); |
- |
- private native void nativeEvaluateJavaScript(long nativeContentViewCoreImpl, |
- String script, JavaScriptCallback callback, boolean startRenderer); |
- |
- private native int nativeGetNativeImeAdapter(long nativeContentViewCoreImpl); |
- |
- private native int nativeGetCurrentRenderProcessId(long nativeContentViewCoreImpl); |
- |
- private native int nativeGetBackgroundColor(long nativeContentViewCoreImpl); |
- |
- private native void nativeOnShow(long nativeContentViewCoreImpl); |
- private native void nativeOnHide(long nativeContentViewCoreImpl); |
- |
- private native void nativeSetUseDesktopUserAgent(long nativeContentViewCoreImpl, |
- boolean enabled, boolean reloadOnChange); |
- private native boolean nativeGetUseDesktopUserAgent(long nativeContentViewCoreImpl); |
- |
- private native void nativeClearSslPreferences(long nativeContentViewCoreImpl); |
- |
- private native void nativeAddJavascriptInterface(long nativeContentViewCoreImpl, Object object, |
- String name, Class requiredAnnotation, HashSet<Object> retainedObjectSet); |
- |
- private native void nativeRemoveJavascriptInterface(long nativeContentViewCoreImpl, |
- String name); |
- |
- private native int nativeGetNavigationHistory(long nativeContentViewCoreImpl, Object context); |
- private native void nativeGetDirectedNavigationHistory(long nativeContentViewCoreImpl, |
- Object context, boolean isForward, int maxEntries); |
- private native String nativeGetOriginalUrlForActiveNavigationEntry( |
- long nativeContentViewCoreImpl); |
- |
- private native void nativeUpdateVSyncParameters(long nativeContentViewCoreImpl, |
- long timebaseMicros, long intervalMicros); |
- |
- private native void nativeOnVSync(long nativeContentViewCoreImpl, long frameTimeMicros); |
- |
- private native boolean nativeOnAnimate(long nativeContentViewCoreImpl, long frameTimeMicros); |
- |
- private native boolean nativePopulateBitmapFromCompositor(long nativeContentViewCoreImpl, |
- Bitmap bitmap); |
- |
- private native void nativeWasResized(long nativeContentViewCoreImpl); |
- |
- private native boolean nativeIsRenderWidgetHostViewReady(long nativeContentViewCoreImpl); |
- |
- private native void nativeExitFullscreen(long nativeContentViewCoreImpl); |
- private native void nativeUpdateTopControlsState(long nativeContentViewCoreImpl, |
- boolean enableHiding, boolean enableShowing, boolean animate); |
- |
- private native void nativeShowImeIfNeeded(long nativeContentViewCoreImpl); |
- |
- private native void nativeAttachExternalVideoSurface( |
- long nativeContentViewCoreImpl, int playerId, Surface surface); |
- |
- private native void nativeDetachExternalVideoSurface( |
- long nativeContentViewCoreImpl, int playerId); |
- |
- private native void nativeSetAccessibilityEnabled( |
- long nativeContentViewCoreImpl, boolean enabled); |
- |
- private native void nativeSendSingleTapUma(long nativeContentViewCoreImpl, |
- int type, int count); |
- |
- private native void nativeSendActionAfterDoubleTapUma(long nativeContentViewCoreImpl, |
- int type, boolean hasDelay, int count); |
- |
- private native void nativeExtractSmartClipData(long nativeContentViewCoreImpl, |
- int x, int y, int w, int h); |
-} |