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

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

Issue 141533006: [Android] Move the java content/ package to content_public/ to start the split. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Small fixes and findbugs line update Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/public/android/java/src/org/chromium/content/browser/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);
-}

Powered by Google App Engine
This is Rietveld 408576698