This source file includes following definitions.
- JNINamespace
- SuppressWarnings
- drawChild
- super_onKeyUp
- super_dispatchKeyEventPreIme
- super_dispatchKeyEvent
- super_onGenericMotionEvent
- super_onConfigurationChanged
- onScrollChanged
- awakenScrollBars
- super_awakenScrollBars
- invokeZoomPicker
- dismissZoomPicker
- updateZoomControls
- onSmartClipDataExtracted
- getVSyncListener
- addVSyncSubscriber
- removeVSyncSubscriber
- resetVSyncNotification
- isVSyncNotificationEnabled
- setNeedsAnimate
- getContext
- getContainerView
- getWebContents
- setViewportSizeOffset
- getViewAndroidDelegate
- setImeAdapterForTest
- getImeAdapterForTest
- setAdapterInputConnectionFactory
- setInputMethodManagerWrapperForTest
- getInputConnectionForTest
- setContainerViewForTest
- createImeAdapter
- initialize
- onNativeContentViewCoreDestroyed
- setContainerViewInternals
- initializeContainerView
- initPopupZoomer
- destroy
- unregisterAccessibilityContentObserver
- isAlive
- getNativeContentViewCore
- setContentViewClient
- getContentViewClient
- getBackgroundColor
- onBackgroundColorChanged
- loadUrl
- stopLoading
- getUrl
- getTitle
- showInterstitialPage
- isShowingInterstitialPage
- consumePendingRendererFrame
- getViewportWidthPix
- getViewportHeightPix
- getPhysicalBackingWidthPix
- getPhysicalBackingHeightPix
- getOverdrawBottomHeightPix
- getViewportSizeOffsetWidthPix
- getViewportSizeOffsetHeightPix
- getContentHeightCss
- getContentWidthCss
- canGoBack
- canGoForward
- canGoToOffset
- goToOffset
- goToNavigationIndex
- goBack
- goForward
- loadIfNecessary
- requestRestoreLoad
- reload
- reloadIgnoringCache
- cancelPendingReload
- continuePendingReload
- clearHistory
- getSelectedText
- isSelectionEditable
- onTouchEvent
- setIgnoreRemainingTouchEvents
- isScrollInProgress
- SuppressWarnings
- onFlingStartEventConsumed
- SuppressWarnings
- onFlingStartEventHadNoConsumer
- SuppressWarnings
- onFlingCancelEventAck
- SuppressWarnings
- onScrollBeginEventAck
- SuppressWarnings
- onScrollUpdateGestureConsumed
- SuppressWarnings
- onScrollEndEventAck
- SuppressWarnings
- onPinchBeginEventAck
- SuppressWarnings
- onPinchEndEventAck
- SuppressWarnings
- onDoubleTapEventAck
- SuppressWarnings
- filterTapOrPressEvent
- sendDoubleTapForTest
- flingForTest
- addGestureStateListener
- removeGestureStateListener
- updateGestureStateListener
- handleJavaScriptResult
- evaluateJavaScript
- evaluateJavaScriptEvenIfNotYetNavigated
- onShow
- getCurrentRenderProcessId
- onHide
- getContentSettings
- onRenderCoordinatesUpdated
- hidePopupDialog
- hideSelectActionBar
- isSelectActionBarShowing
- resetGestureDetectors
- SuppressWarnings
- onAttachedToWindow
- SuppressWarnings
- SuppressLint
- onDetachedFromWindow
- onVisibilityChanged
- onCreateInputConnection
- getAdapterInputConnectionForTest
- getEditableForTest
- onCheckIsTextEditor
- SuppressWarnings
- onConfigurationChanged
- SuppressWarnings
- onSizeChanged
- onLocationInWindowChanged
- onPhysicalBackingSizeChanged
- onOverdrawBottomHeightChanged
- updateAfterSizeChanged
- cancelRequestToScrollFocusedEditableNodeIntoView
- scrollFocusedEditableNodeIntoView
- onWindowFocusChanged
- onFocusChanged
- onKeyUp
- dispatchKeyEventPreIme
- dispatchKeyEvent
- onHoverEvent
- onGenericMotionEvent
- scrollBy
- scrollTo
- getNativeScrollXForTest
- getNativeScrollYForTest
- SuppressWarnings
- computeHorizontalScrollExtent
- SuppressWarnings
- computeHorizontalScrollOffset
- SuppressWarnings
- computeHorizontalScrollRange
- SuppressWarnings
- computeVerticalScrollExtent
- SuppressWarnings
- computeVerticalScrollOffset
- SuppressWarnings
- computeVerticalScrollRange
- SuppressWarnings
- awakenScrollBars
- updateForTapOrPress
- setClickXAndY
- getSingleTapX
- getSingleTapY
- setZoomControlsDelegate
- updateMultiTouchZoomSupport
- updateDoubleTapSupport
- selectPopupMenuItems
- sendOrientationChangeEvent
- setDownloadDelegate
- getDownloadDelegate
- getSelectionHandleController
- getInsertionHandleController
- getInsertionHandleControllerForTest
- getSelectionHandleControllerForTest
- updateHandleScreenPositions
- hideHandles
- showSelectActionBar
- getUseDesktopUserAgent
- setUseDesktopUserAgent
- clearSslPreferences
- isSelectionHandleShowing
- isInsertionHandleShowing
- temporarilyHideTextHandles
- allowTextHandleFadeIn
- scheduleTextHandleFadeIn
- showImeIfNeeded
- hideImeIfNeeded
- SuppressWarnings
- updateFrameInfo
- updateImeAdapter
- SuppressWarnings
- setTitle
- SuppressWarnings
- showSelectPopup
- getSelectPopupForTest
- SuppressWarnings
- showDisambiguationPopup
- SuppressWarnings
- createTouchEventSynthesizer
- SuppressWarnings
- onSelectionChanged
- SuppressWarnings
- onSelectionBoundsChanged
- setSelectionRootBounds
- updateInsertionSelectionVisibleBounds
- SuppressWarnings
- onEvaluateJavaScriptResult
- SuppressWarnings
- showPastePopup
- SuppressWarnings
- onRenderProcessSwap
- SuppressWarnings
- onWebContentsConnected
- attachImeAdapter
- hasFocus
- canZoomIn
- canZoomOut
- zoomIn
- zoomOut
- zoomReset
- pinchByDelta
- invokeZoomPicker
- setAllowJavascriptInterfacesInspection
- addJavascriptInterface
- addPossiblyUnsafeJavascriptInterface
- removeJavascriptInterface
- getScale
- isReady
- startContentIntent
- onAccessibilityStateChanged
- supportsAccessibilityAction
- performAccessibilityAction
- setBrowserAccessibilityManager
- getBrowserAccessibilityManager
- getAccessibilityNodeProvider
- onInitializeAccessibilityNodeInfo
- onInitializeAccessibilityEvent
- isDeviceAccessibilityScriptInjectionEnabled
- isInjectingAccessibilityScript
- setAccessibilityState
- setInjectedAccessibility
- stopCurrentAccessibilityNotifications
- exitFullscreen
- updateTopControlsState
- addToNavigationHistory
- getNavigationHistory
- getDirectedNavigationHistory
- getOriginalUrlForActiveNavigationEntry
- getRenderCoordinates
- getLocationInWindowX
- getLocationInWindowY
- createRect
- onAnimate
- animateIfNecessary
- extractSmartClipData
- onSmartClipDataExtracted
- setSmartClipDataListener
- offerLongPressToEmbedder
- nativeInit
- getContentVideoViewClient
- shouldBlockMediaRequest
- onNativeFlingStopped
- onScreenOrientationChanged
- nativeGetWebContentsAndroid
- nativeOnJavaContentViewCoreDestroyed
- nativeLoadUrl
- nativeGetURL
- nativeGetTitle
- nativeShowInterstitialPage
- nativeIsShowingInterstitialPage
- nativeIsIncognito
- nativeSetFocus
- nativeSendOrientationChangeEvent
- nativeOnTouchEvent
- nativeSendMouseMoveEvent
- nativeSendMouseWheelEvent
- nativeScrollBegin
- nativeScrollEnd
- nativeScrollBy
- nativeFlingStart
- nativeFlingCancel
- nativeSingleTap
- nativeDoubleTap
- nativeLongPress
- nativePinchBegin
- nativePinchEnd
- nativePinchBy
- nativeSelectBetweenCoordinates
- nativeMoveCaret
- nativeResetGestureDetectors
- nativeIgnoreRemainingTouchEvents
- nativeOnWindowFocusLost
- nativeSetDoubleTapSupportForPageEnabled
- nativeSetDoubleTapSupportEnabled
- nativeSetMultiTouchZoomSupportEnabled
- nativeLoadIfNecessary
- nativeRequestRestoreLoad
- nativeStopLoading
- nativeReload
- nativeReloadIgnoringCache
- nativeCancelPendingReload
- nativeContinuePendingReload
- nativeSelectPopupMenuItems
- nativeScrollFocusedEditableNodeIntoView
- nativeClearHistory
- nativeEvaluateJavaScript
- nativeGetNativeImeAdapter
- nativeGetCurrentRenderProcessId
- nativeGetBackgroundColor
- nativeOnShow
- nativeOnHide
- nativeSetUseDesktopUserAgent
- nativeGetUseDesktopUserAgent
- nativeClearSslPreferences
- nativeSetAllowJavascriptInterfacesInspection
- nativeAddJavascriptInterface
- nativeRemoveJavascriptInterface
- nativeGetNavigationHistory
- nativeGetDirectedNavigationHistory
- nativeGetOriginalUrlForActiveNavigationEntry
- nativeUpdateVSyncParameters
- nativeOnVSync
- nativeOnAnimate
- nativeWasResized
- nativeIsRenderWidgetHostViewReady
- nativeExitFullscreen
- nativeUpdateTopControlsState
- nativeShowImeIfNeeded
- nativeSetAccessibilityEnabled
- nativeExtractSmartClipData
package org.chromium.content.browser;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.SearchManager;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
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.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.ResultReceiver;
import android.os.SystemClock;
import android.provider.Browser;
import android.provider.Settings;
import android.text.Editable;
import android.text.Selection;
import android.text.TextUtils;
import android.util.Log;
import android.view.ActionMode;
import android.view.HapticFeedbackConstants;
import android.view.InputDevice;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
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.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.ObserverList;
import org.chromium.base.ObserverList.RewindableIterator;
import org.chromium.base.TraceEvent;
import org.chromium.content.R;
import org.chromium.content.browser.ScreenOrientationListener.ScreenOrientationObserver;
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.content_public.browser.GestureStateListener;
import org.chromium.content_public.browser.WebContents;
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;
@JNINamespace("content")
public class ContentViewCore
implements NavigationClient, AccessibilityStateChangeListener, ScreenOrientationObserver {
private static final String TAG = "ContentViewCore";
private static final float ZOOM_CONTROLS_EPSILON = 0.007f;
private static final int IS_LONG_PRESS = 1;
private static final int IS_LONG_TAP = 2;
private static final int TEXT_HANDLE_FADE_IN_DELAY = 300;
private final Map<String, Object> mJavaScriptInterfaces = new HashMap<String, Object>();
private final HashSet<Object> mRetainedJavaScriptObjects = new HashSet<Object>();
@SuppressWarnings("javadoc")
public interface InternalAccessDelegate {
boolean drawChild(Canvas canvas, View child, long drawingTime);
boolean super_onKeyUp(int keyCode, KeyEvent event);
boolean super_dispatchKeyEventPreIme(KeyEvent event);
boolean super_dispatchKeyEvent(KeyEvent event);
boolean super_onGenericMotionEvent(MotionEvent event);
void super_onConfigurationChanged(Configuration newConfig);
void onScrollChanged(int lPix, int tPix, int oldlPix, int oldtPix);
boolean awakenScrollBars();
boolean super_awakenScrollBars(int startDelay, boolean invalidate);
}
public interface ZoomControlsDelegate {
void invokeZoomPicker();
void dismissZoomPicker();
void updateZoomControls();
}
public interface SmartClipDataListener {
public void onSmartClipDataExtracted(String result);
}
private VSyncManager.Provider mVSyncProvider;
private VSyncManager.Listener mVSyncListener;
private int mVSyncSubscriberCount;
private boolean mVSyncListenerRegistered;
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) {
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;
private long mNativeContentViewCore = 0;
private boolean mInForeground = false;
private final ObserverList<GestureStateListener> mGestureStateListeners;
private final RewindableIterator<GestureStateListener> mGestureStateListenersIterator;
private ZoomControlsDelegate mZoomControlsDelegate;
private PopupZoomer mPopupZoomer;
private SelectPopupDialog mSelectPopupDialog;
private Runnable mFakeMouseMoveRunnable = null;
private ImeAdapter mImeAdapter;
private ImeAdapter.AdapterInputConnectionFactory mAdapterInputConnectionFactory;
private AdapterInputConnection mInputConnection;
private InputMethodManagerWrapper mInputMethodManagerWrapper;
private SelectionHandleController mSelectionHandleController;
private InsertionHandleController mInsertionHandleController;
private Runnable mDeferredHandleFadeInRunnable;
private PositionObserver mPositionObserver;
private PositionObserver.Listener mPositionListener;
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;
private final RenderCoordinates mRenderCoordinates;
private final RenderCoordinates.NormalizedPoint mStartHandlePoint;
private final RenderCoordinates.NormalizedPoint mEndHandlePoint;
private final RenderCoordinates.NormalizedPoint mInsertionHandlePoint;
private final RenderCoordinates.NormalizedPoint mTopLeftVisibilityClippingPoint;
private final RenderCoordinates.NormalizedPoint mBottomRightVisibilityClippingPoint;
private boolean mHasSelection;
private String mLastSelectedText;
private boolean mSelectionEditable;
private ActionMode mActionMode;
private boolean mUnselectAllOnActionModeDismiss;
private ContentViewDownloadDelegate mDownloadDelegate;
private AccessibilityInjector mAccessibilityInjector;
private boolean mNativeAccessibilityAllowed;
private boolean mNativeAccessibilityEnabled;
private BrowserAccessibilityManager mBrowserAccessibilityManager;
private final AccessibilityManager mAccessibilityManager;
private boolean mTouchExplorationEnabled;
private ContentObserver mAccessibilityScriptInjectionObserver;
private final Rect mFocusPreOSKViewportRect = new Rect();
private boolean mPendingRendererFrame = false;
private boolean mNeedAnimate = false;
private boolean mRequestedVSyncForInput = false;
private int mSingleTapX;
private int mSingleTapY;
private boolean mTouchScrollInProgress;
private int mPotentiallyActiveFlingCount;
private ViewAndroid mViewAndroid;
private SmartClipDataListener mSmartClipDataListener = null;
private Editable mEditable;
public static final int INVALID_RENDER_PROCESS_PID = 0;
public ContentViewCore(Context context) {
mContext = context;
mAdapterInputConnectionFactory = new AdapterInputConnectionFactory();
mInputMethodManagerWrapper = new InputMethodManagerWrapper(mContext);
mRenderCoordinates = new RenderCoordinates();
float deviceScaleFactor = getContext().getResources().getDisplayMetrics().density;
String forceScaleFactor = CommandLine.getInstance().getSwitchValue(
ContentSwitches.FORCE_DEVICE_SCALE_FACTOR);
if (forceScaleFactor != null) {
deviceScaleFactor = Float.valueOf(forceScaleFactor);
}
mRenderCoordinates.setDeviceScaleFactor(deviceScaleFactor);
mStartHandlePoint = mRenderCoordinates.createNormalizedPoint();
mEndHandlePoint = mRenderCoordinates.createNormalizedPoint();
mInsertionHandlePoint = mRenderCoordinates.createNormalizedPoint();
mTopLeftVisibilityClippingPoint = mRenderCoordinates.createNormalizedPoint();
mBottomRightVisibilityClippingPoint = mRenderCoordinates.createNormalizedPoint();
mAccessibilityManager = (AccessibilityManager)
getContext().getSystemService(Context.ACCESSIBILITY_SERVICE);
mGestureStateListeners = new ObserverList<GestureStateListener>();
mGestureStateListenersIterator = mGestureStateListeners.rewindableIterator();
mEditable = Editable.Factory.getInstance().newEditable("");
Selection.setSelection(mEditable, 0);
}
@CalledByNative
public Context getContext() {
return mContext;
}
public ViewGroup getContainerView() {
return mContainerView;
}
public WebContents getWebContents() {
return mWebContents;
}
public void setViewportSizeOffset(int offsetXPix, int offsetYPix) {
if (offsetXPix != mViewportSizeOffsetWidthPix ||
offsetYPix != mViewportSizeOffsetHeightPix) {
mViewportSizeOffsetWidthPix = offsetXPix;
mViewportSizeOffsetHeightPix = offsetYPix;
if (mNativeContentViewCore != 0) nativeWasResized(mNativeContentViewCore);
}
}
@VisibleForTesting
public ViewAndroidDelegate getViewAndroidDelegate() {
return new ViewAndroidDelegate() {
@Override
public View acquireAnchorView() {
View anchorView = new View(getContext());
mContainerView.addView(anchorView);
return anchorView;
}
@Override
@SuppressWarnings("deprecation")
public void setAnchorViewPosition(
View view, float x, float y, float width, float height) {
assert view.getParent() == mContainerView;
float scale = (float) DeviceDisplayInfo.create(getContext()).getDIPScale();
int leftMargin = Math.round(x * scale);
int topMargin = Math.round(mRenderCoordinates.getContentOffsetYPix() + y * scale);
int scaledWidth = Math.round(width * scale);
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 android.widget.AbsoluteLayout) {
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 void setImeAdapterForTest(ImeAdapter imeAdapter) {
mImeAdapter = imeAdapter;
}
@VisibleForTesting
public ImeAdapter getImeAdapterForTest() {
return mImeAdapter;
}
@VisibleForTesting
public void setAdapterInputConnectionFactory(AdapterInputConnectionFactory factory) {
mAdapterInputConnectionFactory = factory;
}
@VisibleForTesting
public void setInputMethodManagerWrapperForTest(InputMethodManagerWrapper immw) {
mInputMethodManagerWrapper = immw;
}
@VisibleForTesting
public AdapterInputConnection getInputConnectionForTest() {
return mInputConnection;
}
@VisibleForTesting
public void setContainerViewForTest(ViewGroup view) {
mContainerView = view;
}
private ImeAdapter createImeAdapter(Context context) {
return new ImeAdapter(mInputMethodManagerWrapper,
new ImeAdapter.ImeAdapterDelegate() {
@Override
public void onImeEvent(boolean isFinish) {
getContentViewClient().onImeEvent();
if (!isFinish) {
hideHandles();
}
}
@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) {
getContainerView().getWindowVisibleDisplayFrame(
mFocusPreOSKViewportRect);
} else if (resultCode ==
InputMethodManager.RESULT_UNCHANGED_SHOWN) {
scrollFocusedEditableNodeIntoView();
}
}
};
}
}
);
}
public void initialize(ViewGroup containerView, InternalAccessDelegate internalDispatcher,
long nativeWebContents, WindowAndroid windowAndroid) {
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();
}
mZoomControlsDelegate = new ZoomControlsDelegate() {
@Override
public void invokeZoomPicker() {}
@Override
public void dismissZoomPicker() {}
@Override
public void updateZoomControls() {}
};
mNativeContentViewCore = nativeInit(
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();
}
};
}
@CalledByNative
void onNativeContentViewCoreDestroyed(long nativeContentViewCore) {
assert nativeContentViewCore == mNativeContentViewCore;
mNativeContentViewCore = 0;
}
public void setContainerViewInternals(InternalAccessDelegate internalDispatcher) {
mContainerViewInternals = internalDispatcher;
}
private void initializeContainerView(InternalAccessDelegate internalDispatcher) {
TraceEvent.begin();
mContainerViewInternals = internalDispatcher;
mContainerView.setWillNotDraw(false);
mContainerView.setClickable(true);
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";
}
}
});
}
});
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());
}
return true;
}
@Override
public boolean onLongPress(View v, MotionEvent e) {
if (mNativeContentViewCore != 0) {
nativeLongPress(mNativeContentViewCore, e.getEventTime(), e.getX(), e.getY());
}
return true;
}
};
mPopupZoomer.setOnTapListener(listener);
}
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();
mGestureStateListeners.clear();
ScreenOrientationListener.getInstance().removeObserver(this);
}
private void unregisterAccessibilityContentObserver() {
if (mAccessibilityScriptInjectionObserver == null) {
return;
}
getContext().getContentResolver().unregisterContentObserver(
mAccessibilityScriptInjectionObserver);
mAccessibilityScriptInjectionObserver = null;
}
public boolean isAlive() {
return mNativeContentViewCore != 0;
}
@CalledByNative
public long getNativeContentViewCore() {
return mNativeContentViewCore;
}
public void setContentViewClient(ContentViewClient client) {
if (client == null) {
throw new IllegalArgumentException("The client can't be null.");
}
mContentViewClient = client;
}
ContentViewClient getContentViewClient() {
if (mContentViewClient == null) {
mContentViewClient = new ContentViewClient();
}
return mContentViewClient;
}
public int getBackgroundColor() {
if (mNativeContentViewCore != 0) {
return nativeGetBackgroundColor(mNativeContentViewCore);
}
return Color.WHITE;
}
@CalledByNative
private void onBackgroundColorChanged(int color) {
getContentViewClient().onBackgroundColorChanged(color);
}
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);
}
public void stopLoading() {
if (mNativeContentViewCore != 0) nativeStopLoading(mNativeContentViewCore);
}
public String getUrl() {
if (mNativeContentViewCore != 0) return nativeGetURL(mNativeContentViewCore);
return null;
}
public String getTitle() {
if (mNativeContentViewCore != 0) return nativeGetTitle(mNativeContentViewCore);
return null;
}
@VisibleForTesting
public void showInterstitialPage(
String url, InterstitialPageDelegateAndroid delegate) {
if (mNativeContentViewCore == 0) return;
nativeShowInterstitialPage(mNativeContentViewCore, url, delegate.getNative());
}
public boolean isShowingInterstitialPage() {
return mNativeContentViewCore == 0 ?
false : nativeIsShowingInterstitialPage(mNativeContentViewCore);
}
public boolean consumePendingRendererFrame() {
boolean hadPendingFrame = mPendingRendererFrame;
mPendingRendererFrame = false;
return hadPendingFrame;
}
@CalledByNative
public int getViewportWidthPix() { return mViewportWidthPix; }
@CalledByNative
public int getViewportHeightPix() { return mViewportHeightPix; }
@CalledByNative
public int getPhysicalBackingWidthPix() { return mPhysicalBackingWidthPix; }
@CalledByNative
public int getPhysicalBackingHeightPix() { return mPhysicalBackingHeightPix; }
@CalledByNative
public int getOverdrawBottomHeightPix() { return mOverdrawBottomHeightPix; }
@CalledByNative
public int getViewportSizeOffsetWidthPix() { return mViewportSizeOffsetWidthPix; }
@CalledByNative
public int getViewportSizeOffsetHeightPix() { return mViewportSizeOffsetHeightPix; }
public float getContentHeightCss() {
return mRenderCoordinates.getContentHeightCss();
}
public float getContentWidthCss() {
return mRenderCoordinates.getContentWidthCss();
}
public boolean canGoBack() {
return mWebContents != null && mWebContents.getNavigationController().canGoBack();
}
public boolean canGoForward() {
return mWebContents != null && mWebContents.getNavigationController().canGoForward();
}
public boolean canGoToOffset(int offset) {
return mWebContents != null &&
mWebContents.getNavigationController().canGoToOffset(offset);
}
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);
}
}
public void goBack() {
if (mWebContents != null) mWebContents.getNavigationController().goBack();
}
public void goForward() {
if (mWebContents != null) mWebContents.getNavigationController().goForward();
}
public void loadIfNecessary() {
if (mNativeContentViewCore != 0) nativeLoadIfNecessary(mNativeContentViewCore);
}
public void requestRestoreLoad() {
if (mNativeContentViewCore != 0) nativeRequestRestoreLoad(mNativeContentViewCore);
}
public void reload(boolean checkForRepost) {
mAccessibilityInjector.addOrRemoveAccessibilityApisIfNecessary();
if (mNativeContentViewCore != 0) {
nativeReload(mNativeContentViewCore, checkForRepost);
}
}
public void reloadIgnoringCache(boolean checkForRepost) {
mAccessibilityInjector.addOrRemoveAccessibilityApisIfNecessary();
if (mNativeContentViewCore != 0) {
nativeReloadIgnoringCache(mNativeContentViewCore, checkForRepost);
}
}
public void cancelPendingReload() {
if (mNativeContentViewCore != 0) nativeCancelPendingReload(mNativeContentViewCore);
}
public void continuePendingReload() {
if (mNativeContentViewCore != 0) nativeContinuePendingReload(mNativeContentViewCore);
}
public void clearHistory() {
if (mNativeContentViewCore != 0) nativeClearHistory(mNativeContentViewCore);
}
public String getSelectedText() {
return mHasSelection ? mLastSelectedText : "";
}
public boolean isSelectionEditable() {
return mHasSelection ? mSelectionEditable : false;
}
public boolean onTouchEvent(MotionEvent event) {
cancelRequestToScrollFocusedEditableNodeIntoView();
if (!mRequestedVSyncForInput) {
mRequestedVSyncForInput = true;
addVSyncSubscriber();
}
final int eventAction = event.getActionMasked();
if (eventAction != MotionEvent.ACTION_DOWN
&& eventAction != MotionEvent.ACTION_UP
&& eventAction != MotionEvent.ACTION_CANCEL
&& eventAction != MotionEvent.ACTION_MOVE
&& eventAction != MotionEvent.ACTION_POINTER_DOWN
&& eventAction != MotionEvent.ACTION_POINTER_UP) {
return false;
}
if (mNativeContentViewCore == 0) return false;
final int pointerCount = event.getPointerCount();
return nativeOnTouchEvent(mNativeContentViewCore, event,
event.getEventTime(), eventAction,
pointerCount, event.getHistorySize(), event.getActionIndex(),
event.getX(), event.getY(),
pointerCount > 1 ? event.getX(1) : 0,
pointerCount > 1 ? event.getY(1) : 0,
event.getPointerId(0), pointerCount > 1 ? event.getPointerId(1) : -1,
event.getTouchMajor(), pointerCount > 1 ? event.getTouchMajor(1) : 0);
}
public void setIgnoreRemainingTouchEvents() {
if (mNativeContentViewCore == 0) return;
nativeIgnoreRemainingTouchEvents(mNativeContentViewCore);
}
public boolean isScrollInProgress() {
return mTouchScrollInProgress || mPotentiallyActiveFlingCount > 0;
}
@SuppressWarnings("unused")
@CalledByNative
private void onFlingStartEventConsumed(int vx, int vy) {
mTouchScrollInProgress = false;
mPotentiallyActiveFlingCount++;
temporarilyHideTextHandles();
for (mGestureStateListenersIterator.rewind();
mGestureStateListenersIterator.hasNext();) {
mGestureStateListenersIterator.next().onFlingStartGesture(
vx, vy, computeVerticalScrollOffset(), computeVerticalScrollExtent());
}
}
@SuppressWarnings("unused")
@CalledByNative
private void onFlingStartEventHadNoConsumer(int vx, int vy) {
mTouchScrollInProgress = false;
for (mGestureStateListenersIterator.rewind();
mGestureStateListenersIterator.hasNext();) {
mGestureStateListenersIterator.next().onUnhandledFlingStartEvent(vx, vy);
}
}
@SuppressWarnings("unused")
@CalledByNative
private void onFlingCancelEventAck() {
updateGestureStateListener(GestureEventType.FLING_CANCEL);
}
@SuppressWarnings("unused")
@CalledByNative
private void onScrollBeginEventAck() {
mTouchScrollInProgress = true;
temporarilyHideTextHandles();
mZoomControlsDelegate.invokeZoomPicker();
updateGestureStateListener(GestureEventType.SCROLL_START);
}
@SuppressWarnings("unused")
@CalledByNative
private void onScrollUpdateGestureConsumed() {
mZoomControlsDelegate.invokeZoomPicker();
for (mGestureStateListenersIterator.rewind();
mGestureStateListenersIterator.hasNext();) {
mGestureStateListenersIterator.next().onScrollUpdateGestureConsumed();
}
}
@SuppressWarnings("unused")
@CalledByNative
private void onScrollEndEventAck() {
mTouchScrollInProgress = false;
updateGestureStateListener(GestureEventType.SCROLL_END);
}
@SuppressWarnings("unused")
@CalledByNative
private void onPinchBeginEventAck() {
temporarilyHideTextHandles();
updateGestureStateListener(GestureEventType.PINCH_BEGIN);
}
@SuppressWarnings("unused")
@CalledByNative
private void onPinchEndEventAck() {
updateGestureStateListener(GestureEventType.PINCH_END);
}
@SuppressWarnings("unused")
@CalledByNative
private void onDoubleTapEventAck() {
temporarilyHideTextHandles();
}
@SuppressWarnings("unused")
@CalledByNative
private boolean filterTapOrPressEvent(int type, int x, int y) {
if (type == GestureEventType.LONG_PRESS && offerLongPressToEmbedder()) {
return true;
}
updateForTapOrPress(type, x, y);
return false;
}
@VisibleForTesting
public void sendDoubleTapForTest(long timeMs, int x, int y) {
if (mNativeContentViewCore == 0) return;
nativeDoubleTap(mNativeContentViewCore, timeMs, x, y);
}
@VisibleForTesting
public void flingForTest(long timeMs, int x, int y, int velocityX, int velocityY) {
if (mNativeContentViewCore == 0) return;
nativeFlingCancel(mNativeContentViewCore, timeMs);
nativeScrollBegin(mNativeContentViewCore, timeMs, x, y, velocityX, velocityY);
nativeFlingStart(mNativeContentViewCore, timeMs, x, y, velocityX, velocityY);
}
public void addGestureStateListener(GestureStateListener listener) {
mGestureStateListeners.addObserver(listener);
}
public void removeGestureStateListener(GestureStateListener listener) {
mGestureStateListeners.removeObserver(listener);
}
void updateGestureStateListener(int gestureType) {
for (mGestureStateListenersIterator.rewind();
mGestureStateListenersIterator.hasNext();) {
GestureStateListener listener = mGestureStateListenersIterator.next();
switch (gestureType) {
case GestureEventType.PINCH_BEGIN:
listener.onPinchStarted();
break;
case GestureEventType.PINCH_END:
listener.onPinchEnded();
break;
case GestureEventType.FLING_END:
listener.onFlingEndGesture(
computeVerticalScrollOffset(),
computeVerticalScrollExtent());
break;
case GestureEventType.FLING_CANCEL:
listener.onFlingCancelGesture();
break;
case GestureEventType.SCROLL_START:
listener.onScrollStarted(
computeVerticalScrollOffset(),
computeVerticalScrollExtent());
break;
case GestureEventType.SCROLL_END:
listener.onScrollEnded(
computeVerticalScrollOffset(),
computeVerticalScrollExtent());
break;
default:
break;
}
}
}
public interface JavaScriptCallback {
void handleJavaScriptResult(String jsonResult);
}
public void evaluateJavaScript(String script, JavaScriptCallback callback) {
if (mNativeContentViewCore == 0) return;
nativeEvaluateJavaScript(mNativeContentViewCore, script, callback, false);
}
public void evaluateJavaScriptEvenIfNotYetNavigated(String script) {
if (mNativeContentViewCore == 0) return;
nativeEvaluateJavaScript(mNativeContentViewCore, script, null, true);
}
public void onShow() {
assert mNativeContentViewCore != 0;
if (!mInForeground) {
ChildProcessLauncher.getBindingManager().setInForeground(getCurrentRenderProcessId(),
true);
}
mInForeground = true;
nativeOnShow(mNativeContentViewCore);
setAccessibilityState(mAccessibilityManager.isEnabled());
}
public int getCurrentRenderProcessId() {
return nativeGetCurrentRenderProcessId(mNativeContentViewCore);
}
public void onHide() {
assert mNativeContentViewCore != 0;
if (mInForeground) {
ChildProcessLauncher.getBindingManager().setInForeground(getCurrentRenderProcessId(),
false);
}
mInForeground = false;
hidePopupDialog();
setInjectedAccessibility(false);
nativeOnHide(mNativeContentViewCore);
}
public ContentSettings getContentSettings() {
return mContentSettings;
}
private void onRenderCoordinatesUpdated() {
if (mNativeContentViewCore == 0) return;
nativeSetDoubleTapSupportForPageEnabled(mNativeContentViewCore,
!mRenderCoordinates.hasMobileViewport() && !mRenderCoordinates.hasFixedPageScale());
}
private void hidePopupDialog() {
if (mSelectPopupDialog != null) {
mSelectPopupDialog.hide();
mSelectPopupDialog = null;
}
hideHandles();
hideSelectActionBar();
}
void hideSelectActionBar() {
if (mActionMode != null) {
mActionMode.finish();
mActionMode = null;
}
}
public boolean isSelectActionBarShowing() {
return mActionMode != null;
}
private void resetGestureDetectors() {
if (mNativeContentViewCore == 0) return;
nativeResetGestureDetectors(mNativeContentViewCore);
}
@SuppressWarnings("javadoc")
public void onAttachedToWindow() {
setAccessibilityState(mAccessibilityManager.isEnabled());
ScreenOrientationListener.getInstance().addObserver(this, mContext);
}
@SuppressWarnings("javadoc")
@SuppressLint("MissingSuperCall")
public void onDetachedFromWindow() {
setInjectedAccessibility(false);
hidePopupDialog();
mZoomControlsDelegate.dismissZoomPicker();
unregisterAccessibilityContentObserver();
ScreenOrientationListener.getInstance().removeObserver(this);
}
public void onVisibilityChanged(View changedView, int visibility) {
if (visibility != View.VISIBLE) {
mZoomControlsDelegate.dismissZoomPicker();
}
}
public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
if (!mImeAdapter.hasTextInputType()) {
outAttrs.imeOptions = EditorInfo.IME_FLAG_NO_FULLSCREEN;
}
mInputConnection = mAdapterInputConnectionFactory.get(mContainerView, mImeAdapter,
mEditable, outAttrs);
return mInputConnection;
}
@VisibleForTesting
public AdapterInputConnection getAdapterInputConnectionForTest() {
return mInputConnection;
}
@VisibleForTesting
public Editable getEditableForTest() {
return mEditable;
}
public boolean onCheckIsTextEditor() {
return mImeAdapter.hasTextInputType();
}
@SuppressWarnings("javadoc")
public void onConfigurationChanged(Configuration newConfig) {
TraceEvent.begin();
if (newConfig.keyboard != Configuration.KEYBOARD_NOKEYS) {
mImeAdapter.attach(nativeGetNativeImeAdapter(mNativeContentViewCore),
ImeAdapter.getTextInputTypeNone());
mInputMethodManagerWrapper.restartInput(mContainerView);
}
mContainerViewInternals.super_onConfigurationChanged(newConfig);
mContainerView.requestLayout();
TraceEvent.end();
}
@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();
}
public void onLocationInWindowChanged(int x, int y) {
mLocationInWindowX = x;
mLocationInWindowY = y;
}
public void onPhysicalBackingSizeChanged(int wPix, int hPix) {
if (mPhysicalBackingWidthPix == wPix && mPhysicalBackingHeightPix == hPix) return;
mPhysicalBackingWidthPix = wPix;
mPhysicalBackingHeightPix = hPix;
if (mNativeContentViewCore != 0) {
nativeWasResized(mNativeContentViewCore);
}
}
public void onOverdrawBottomHeightChanged(int overdrawHeightPix) {
if (mOverdrawBottomHeightPix == overdrawHeightPix) return;
mOverdrawBottomHeightPix = overdrawHeightPix;
if (mNativeContentViewCore != 0) {
nativeWasResized(mNativeContentViewCore);
}
}
private void updateAfterSizeChanged() {
mPopupZoomer.hide(false);
if (!mFocusPreOSKViewportRect.isEmpty()) {
Rect rect = new Rect();
getContainerView().getWindowVisibleDisplayFrame(rect);
if (!rect.equals(mFocusPreOSKViewportRect)) {
if (rect.width() == mFocusPreOSKViewportRect.width()) {
scrollFocusedEditableNodeIntoView();
}
cancelRequestToScrollFocusedEditableNodeIntoView();
}
}
}
private void cancelRequestToScrollFocusedEditableNodeIntoView() {
mFocusPreOSKViewportRect.setEmpty();
}
private void scrollFocusedEditableNodeIntoView() {
if (mNativeContentViewCore == 0) return;
nativeScrollFocusedEditableNodeIntoView(mNativeContentViewCore);
}
public void onWindowFocusChanged(boolean hasWindowFocus) {
if (!hasWindowFocus) {
if (mNativeContentViewCore == 0) return;
nativeOnWindowFocusLost(mNativeContentViewCore);
}
}
public void onFocusChanged(boolean gainFocus) {
if (!gainFocus) {
hideImeIfNeeded();
}
if (mNativeContentViewCore != 0) nativeSetFocus(mNativeContentViewCore, gainFocus);
}
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);
}
public boolean dispatchKeyEventPreIme(KeyEvent event) {
try {
TraceEvent.begin();
return mContainerViewInternals.super_dispatchKeyEventPreIme(event);
} finally {
TraceEvent.end();
}
}
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);
}
public boolean onHoverEvent(MotionEvent event) {
TraceEvent.begin("onHoverEvent");
if (mBrowserAccessibilityManager != null) {
return mBrowserAccessibilityManager.onHoverEvent(event);
}
if (mTouchExplorationEnabled && event.getAction() == MotionEvent.ACTION_HOVER_EXIT) {
return true;
}
mContainerView.removeCallbacks(mFakeMouseMoveRunnable);
if (mNativeContentViewCore != 0) {
nativeSendMouseMoveEvent(mNativeContentViewCore, event.getEventTime(),
event.getX(), event.getY());
}
TraceEvent.end("onHoverEvent");
return true;
}
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);
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);
}
public void scrollBy(int xPix, int yPix) {
if (mNativeContentViewCore != 0) {
nativeScrollBy(mNativeContentViewCore,
SystemClock.uptimeMillis(), 0, 0, xPix, yPix);
}
}
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 = SystemClock.uptimeMillis();
nativeScrollBegin(mNativeContentViewCore, time,
xCurrentPix, yCurrentPix, -dxPix, -dyPix);
nativeScrollBy(mNativeContentViewCore,
time, xCurrentPix, yCurrentPix, dxPix, dyPix);
nativeScrollEnd(mNativeContentViewCore, time);
}
}
public int getNativeScrollXForTest() {
return mRenderCoordinates.getScrollXPixInt();
}
public int getNativeScrollYForTest() {
return mRenderCoordinates.getScrollYPixInt();
}
@SuppressWarnings("javadoc")
public int computeHorizontalScrollExtent() {
return mRenderCoordinates.getLastFrameViewportWidthPixInt();
}
@SuppressWarnings("javadoc")
public int computeHorizontalScrollOffset() {
return mRenderCoordinates.getScrollXPixInt();
}
@SuppressWarnings("javadoc")
public int computeHorizontalScrollRange() {
return mRenderCoordinates.getContentWidthPixInt();
}
@SuppressWarnings("javadoc")
public int computeVerticalScrollExtent() {
return mRenderCoordinates.getLastFrameViewportHeightPixInt();
}
@SuppressWarnings("javadoc")
public int computeVerticalScrollOffset() {
return mRenderCoordinates.getScrollYPixInt();
}
@SuppressWarnings("javadoc")
public int computeVerticalScrollRange() {
return mRenderCoordinates.getContentHeightPixInt();
}
@SuppressWarnings("javadoc")
public boolean awakenScrollBars(int startDelay, boolean invalidate) {
if (mContainerView.getScrollBarStyle() == View.SCROLLBARS_INSIDE_OVERLAY) {
return false;
} else {
return mContainerViewInternals.super_awakenScrollBars(startDelay, invalidate);
}
}
private void updateForTapOrPress(int type, float xPix, float yPix) {
if (type != GestureEventType.SINGLE_TAP_CONFIRMED
&& type != GestureEventType.SINGLE_TAP_UP
&& type != GestureEventType.LONG_PRESS
&& type != GestureEventType.LONG_TAP) {
return;
}
if (mContainerView.isFocusable() && mContainerView.isFocusableInTouchMode()
&& !mContainerView.isFocused()) {
mContainerView.requestFocus();
}
if (!mPopupZoomer.isShowing()) mPopupZoomer.setLastTouch(xPix, yPix);
if (type == GestureEventType.LONG_PRESS
|| type == GestureEventType.LONG_TAP) {
getInsertionHandleController().allowAutomaticShowing();
getSelectionHandleController().allowAutomaticShowing();
} else {
setClickXAndY((int) xPix, (int) yPix);
if (mSelectionEditable) getInsertionHandleController().allowAutomaticShowing();
}
}
private void setClickXAndY(int x, int y) {
mSingleTapX = x;
mSingleTapY = y;
}
public int getSingleTapX() {
return mSingleTapX;
}
public int getSingleTapY() {
return mSingleTapY;
}
public void setZoomControlsDelegate(ZoomControlsDelegate zoomControlsDelegate) {
mZoomControlsDelegate = zoomControlsDelegate;
}
public void updateMultiTouchZoomSupport(boolean supportsMultiTouchZoom) {
if (mNativeContentViewCore == 0) return;
nativeSetMultiTouchZoomSupportEnabled(mNativeContentViewCore, supportsMultiTouchZoom);
}
public void updateDoubleTapSupport(boolean supportsDoubleTap) {
if (mNativeContentViewCore == 0) return;
nativeSetDoubleTapSupportEnabled(mNativeContentViewCore, supportsDoubleTap);
}
public void selectPopupMenuItems(int[] indices) {
if (mNativeContentViewCore != 0) {
nativeSelectPopupMenuItems(mNativeContentViewCore, indices);
}
mSelectPopupDialog = null;
}
@VisibleForTesting
void sendOrientationChangeEvent(int orientation) {
if (mNativeContentViewCore == 0) return;
nativeSendOrientationChangeEvent(mNativeContentViewCore, orientation);
}
public void setDownloadDelegate(ContentViewDownloadDelegate delegate) {
mDownloadDelegate = delegate;
}
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();
updateInsertionSelectionVisibleBounds();
}
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();
updateInsertionSelectionVisibleBounds();
}
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;
}
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) {
}
}
@Override
public void search() {
final String query = getSelectedText();
if (TextUtils.isEmpty(query)) return;
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) {
}
}
@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;
if (mContainerView.getParent() != null) {
mActionMode = mContainerView.startActionMode(
getContentViewClient().getSelectActionModeCallback(getContext(), actionHandler,
nativeIsIncognito(mNativeContentViewCore)));
}
mUnselectAllOnActionModeDismiss = true;
if (mActionMode == null) {
mImeAdapter.unselect();
} else {
getContentViewClient().onContextualActionBarShown();
}
}
public boolean getUseDesktopUserAgent() {
if (mNativeContentViewCore != 0) {
return nativeGetUseDesktopUserAgent(mNativeContentViewCore);
}
return false;
}
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 temporarilyHideTextHandles() {
if (isSelectionHandleShowing() && !mSelectionHandleController.isDragging()) {
mSelectionHandleController.setHandleVisibility(HandleView.INVISIBLE);
}
if (isInsertionHandleShowing() && !mInsertionHandleController.isDragging()) {
mInsertionHandleController.setHandleVisibility(HandleView.INVISIBLE);
}
scheduleTextHandleFadeIn();
}
private boolean allowTextHandleFadeIn() {
if (mTouchScrollInProgress) return false;
if (mPopupZoomer.isShowing()) return false;
return true;
}
private void scheduleTextHandleFadeIn() {
if (!isInsertionHandleShowing() && !isSelectionHandleShowing()) return;
if (mDeferredHandleFadeInRunnable == null) {
mDeferredHandleFadeInRunnable = new Runnable() {
@Override
public void run() {
if (!allowTextHandleFadeIn()) {
scheduleTextHandleFadeIn();
} else {
if (isSelectionHandleShowing()) {
mSelectionHandleController.beginHandleFadeIn();
}
if (isInsertionHandleShowing()) {
mInsertionHandleController.beginHandleFadeIn();
}
}
}
};
}
mContainerView.removeCallbacks(mDeferredHandleFadeInRunnable);
mContainerView.postDelayed(mDeferredHandleFadeInRunnable, TEXT_HANDLE_FADE_IN_DELAY);
}
public void showImeIfNeeded() {
if (mNativeContentViewCore != 0) nativeShowImeIfNeeded(mNativeContentViewCore);
}
public void hideImeIfNeeded() {
if (mInputMethodManagerWrapper.isActive(mContainerView)) {
mInputMethodManagerWrapper.hideSoftInputFromWindow(
mContainerView.getWindowToken(), 0, null);
}
getContentViewClient().onImeStateChangeRequested(false);
}
@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");
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 (scrollChanged || contentOffsetChanged) {
for (mGestureStateListenersIterator.rewind();
mGestureStateListenersIterator.hasNext();) {
mGestureStateListenersIterator.next().onScrollOffsetOrExtentChanged(
computeVerticalScrollOffset(),
computeVerticalScrollExtent());
}
}
if (needTemporarilyHideHandles) temporarilyHideTextHandles();
if (needUpdateZoomControls) mZoomControlsDelegate.updateZoomControls();
if (contentOffsetChanged) updateHandleScreenPositions();
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();
}
}
@CalledByNative
private void updateImeAdapter(long 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, 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);
}
@SuppressWarnings("unused")
@CalledByNative
private void showSelectPopup(String[] items, int[] enabled, boolean multiple,
int[] selectedIndices) {
if (mContainerView.getParent() == null || mContainerView.getVisibility() != View.VISIBLE) {
selectPopupMenuItems(null);
return;
}
if (mSelectPopupDialog != null) {
mSelectPopupDialog.hide();
mSelectPopupDialog = null;
}
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]));
}
mSelectPopupDialog = SelectPopupDialog.show(this, popupItems, multiple, selectedIndices);
}
public SelectPopupDialog getSelectPopupForTest() {
return mSelectPopupDialog;
}
@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;
getContentViewClient().onSelectionChanged(text);
}
@SuppressWarnings("unused")
@CalledByNative
private void onSelectionBoundsChanged(Rect anchorRectDip, int anchorDir, Rect focusRectDip,
int focusDir, boolean isAnchorFirst) {
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()) {
mContainerView.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
}
} else {
mUnselectAllOnActionModeDismiss = false;
hideSelectActionBar();
if (x1 != 0 && y1 != 0 && mSelectionEditable) {
if (mSelectionHandleController != null) {
mSelectionHandleController.hide();
}
mInsertionHandlePoint.setLocalDip(x1, y1);
getInsertionHandleController().onCursorPositionChanged();
updateHandleScreenPositions();
if (mInputMethodManagerWrapper.isWatchingCursor(mContainerView)) {
final int xPix = (int) mInsertionHandlePoint.getXPix();
final int yPix = (int) mInsertionHandlePoint.getYPix();
mInputMethodManagerWrapper.updateCursor(
mContainerView, xPix, yPix, xPix, yPix);
}
} else {
if (mSelectionHandleController != null) {
mSelectionHandleController.hideAndDisallowAutomaticShowing();
}
if (mInsertionHandleController != null) {
mInsertionHandleController.hideAndDisallowAutomaticShowing();
}
}
mHasSelection = false;
}
if (isSelectionHandleShowing() || isInsertionHandleShowing()) {
mPositionObserver.addListener(mPositionListener);
}
}
@CalledByNative
private void setSelectionRootBounds(Rect bounds) {
mTopLeftVisibilityClippingPoint.setLocalDip(bounds.left, bounds.top);
mBottomRightVisibilityClippingPoint.setLocalDip(bounds.right, bounds.bottom);
updateInsertionSelectionVisibleBounds();
}
private void updateInsertionSelectionVisibleBounds() {
if (mSelectionHandleController == null && mInsertionHandleController == null) {
return;
}
int x1 = Math.round(mTopLeftVisibilityClippingPoint.getXPix());
int y1 = Math.round(mTopLeftVisibilityClippingPoint.getYPix());
int x2 = Math.round(mBottomRightVisibilityClippingPoint.getXPix());
int y2 = Math.round(mBottomRightVisibilityClippingPoint.getYPix());
if (mSelectionHandleController != null) {
mSelectionHandleController.setVisibleClippingRectangle(x1, y1, x2, y2);
}
if (mInsertionHandleController != null) {
mInsertionHandleController.setVisibleClippingRectangle(x1, y1, x2, y2);
}
}
@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();
}
public void attachImeAdapter() {
if (mImeAdapter != null && mNativeContentViewCore != 0) {
mImeAdapter.attach(nativeGetNativeImeAdapter(mNativeContentViewCore));
}
}
@CalledByNative
public boolean hasFocus() {
return mContainerView.hasFocus();
}
public boolean canZoomIn() {
final float zoomInExtent = mRenderCoordinates.getMaxPageScaleFactor()
- mRenderCoordinates.getPageScaleFactor();
return zoomInExtent > ZOOM_CONTROLS_EPSILON;
}
public boolean canZoomOut() {
final float zoomOutExtent = mRenderCoordinates.getPageScaleFactor()
- mRenderCoordinates.getMinPageScaleFactor();
return zoomOutExtent > ZOOM_CONTROLS_EPSILON;
}
public boolean zoomIn() {
if (!canZoomIn()) {
return false;
}
return pinchByDelta(1.25f);
}
public boolean zoomOut() {
if (!canZoomOut()) {
return false;
}
return pinchByDelta(0.8f);
}
public boolean zoomReset() {
if (!canZoomOut()) return false;
return pinchByDelta(
mRenderCoordinates.getMinPageScaleFactor()
/ mRenderCoordinates.getPageScaleFactor());
}
public boolean pinchByDelta(float delta) {
if (mNativeContentViewCore == 0) return false;
long timeMs = SystemClock.uptimeMillis();
int xPix = getViewportWidthPix() / 2;
int yPix = getViewportHeightPix() / 2;
nativePinchBegin(mNativeContentViewCore, timeMs, xPix, yPix);
nativePinchBy(mNativeContentViewCore, timeMs, xPix, yPix, delta);
nativePinchEnd(mNativeContentViewCore, timeMs);
return true;
}
public void invokeZoomPicker() {
mZoomControlsDelegate.invokeZoomPicker();
}
public void setAllowJavascriptInterfacesInspection(boolean allow) {
nativeSetAllowJavascriptInterfacesInspection(mNativeContentViewCore, allow);
}
public void addJavascriptInterface(Object object, String name) {
addPossiblyUnsafeJavascriptInterface(object, name, JavascriptInterface.class);
}
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);
}
}
public void removeJavascriptInterface(String name) {
mJavaScriptInterfaces.remove(name);
if (mNativeContentViewCore != 0) {
nativeRemoveJavascriptInterface(mNativeContentViewCore, name);
}
}
public float getScale() {
return mRenderCoordinates.getPageScaleFactor();
}
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);
}
public boolean supportsAccessibilityAction(int action) {
return mAccessibilityInjector.supportsAccessibilityAction(action);
}
public boolean performAccessibilityAction(int action, Bundle arguments) {
if (mAccessibilityInjector.supportsAccessibilityAction(action)) {
return mAccessibilityInjector.performAccessibilityAction(action, arguments);
}
return false;
}
public void setBrowserAccessibilityManager(BrowserAccessibilityManager manager) {
mBrowserAccessibilityManager = manager;
}
public BrowserAccessibilityManager getBrowserAccessibilityManager() {
return mBrowserAccessibilityManager;
}
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;
}
public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
mAccessibilityInjector.onInitializeAccessibilityNodeInfo(info);
}
public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
event.setClassName(this.getClass().getName());
event.setScrollX(mRenderCoordinates.getScrollXPixInt());
event.setScrollY(mRenderCoordinates.getScrollYPixInt());
int maxScrollXPix = Math.max(0, mRenderCoordinates.getMaxHorizontalScrollPixInt());
int maxScrollYPix = Math.max(0, mRenderCoordinates.getMaxVerticalScrollPixInt());
event.setScrollable(maxScrollXPix > 0 || maxScrollYPix > 0);
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);
}
}
public boolean isDeviceAccessibilityScriptInjectionEnabled() {
try {
if (!CommandLine.getInstance().hasSwitch(
ContentSwitches.ENABLE_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) {
} catch (IllegalAccessException e) {
}
return false;
}
public boolean isInjectingAccessibilityScript() {
return mAccessibilityInjector.accessibilityIsAvailable();
}
public void setAccessibilityState(boolean state) {
if (!state) {
setInjectedAccessibility(false);
mNativeAccessibilityAllowed = false;
mTouchExplorationEnabled = false;
} else {
boolean useScriptInjection = isDeviceAccessibilityScriptInjectionEnabled();
setInjectedAccessibility(useScriptInjection);
mNativeAccessibilityAllowed = !useScriptInjection;
mTouchExplorationEnabled = mAccessibilityManager.isTouchExplorationEnabled();
}
}
public void setInjectedAccessibility(boolean enabled) {
mAccessibilityInjector.addOrRemoveAccessibilityApisIfNecessary();
mAccessibilityInjector.setScriptEnabled(enabled);
}
public void stopCurrentAccessibilityNotifications() {
mAccessibilityInjector.onPageLostFocus();
}
public void exitFullscreen() {
if (mNativeContentViewCore != 0) nativeExitFullscreen(mNativeContentViewCore);
}
public void updateTopControlsState(boolean enableHiding, boolean enableShowing,
boolean animate) {
if (mNativeContentViewCore != 0) {
nativeUpdateTopControlsState(
mNativeContentViewCore, enableHiding, enableShowing, animate);
}
}
@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);
}
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;
}
public String getOriginalUrlForActiveNavigationEntry() {
if (mNativeContentViewCore != 0) {
return nativeGetOriginalUrlForActiveNavigationEntry(mNativeContentViewCore);
}
return "";
}
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);
}
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();
}
}
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;
}
private boolean offerLongPressToEmbedder() {
return mContainerView.performLongClick();
}
private native long nativeInit(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() {
mTouchScrollInProgress = false;
if (mPotentiallyActiveFlingCount > 0) mPotentiallyActiveFlingCount--;
updateGestureStateListener(GestureEventType.FLING_END);
}
@Override
public void onScreenOrientationChanged(int orientation) {
sendOrientationChangeEvent(orientation);
}
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);
private native boolean nativeOnTouchEvent(
long nativeContentViewCoreImpl, MotionEvent event,
long timeMs, int action, int pointerCount, int historySize, int actionIndex,
float x0, float y0, float x1, float y1,
int pointerId0, int pointerId1,
float touchMajor0, float touchMajor1);
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);
private native void nativeDoubleTap(
long nativeContentViewCoreImpl, long timeMs, float x, float y);
private native void nativeLongPress(
long nativeContentViewCoreImpl, long timeMs, float x, float y);
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 nativeResetGestureDetectors(long nativeContentViewCoreImpl);
private native void nativeIgnoreRemainingTouchEvents(long nativeContentViewCoreImpl);
private native void nativeOnWindowFocusLost(long nativeContentViewCoreImpl);
private native void nativeSetDoubleTapSupportForPageEnabled(
long nativeContentViewCoreImpl, boolean enabled);
private native void nativeSetDoubleTapSupportEnabled(
long nativeContentViewCoreImpl, boolean enabled);
private native void nativeSetMultiTouchZoomSupportEnabled(
long nativeContentViewCoreImpl, boolean enabled);
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 nativeClearHistory(long nativeContentViewCoreImpl);
private native void nativeEvaluateJavaScript(long nativeContentViewCoreImpl,
String script, JavaScriptCallback callback, boolean startRenderer);
private native long 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 nativeSetAllowJavascriptInterfacesInspection(
long nativeContentViewCoreImpl, boolean allow);
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 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 nativeSetAccessibilityEnabled(
long nativeContentViewCoreImpl, boolean enabled);
private native void nativeExtractSmartClipData(long nativeContentViewCoreImpl,
int x, int y, int w, int h);
}