private static final float MAX_SLOPE_FOR_DIAG = 1.5f;
private static final int MIN_BREAK_SNAP_CROSS_DISTANCE = 80;
<<<<<<< HEAD
private static int sign(float x) {
return x > 0 ? 1 : (x < 0 ? -1 : 0);
}
// if the page can scroll <= this value, we won't allow the drag tracker
// to have any effect.
private static final int MIN_SCROLL_AMOUNT_TO_DISABLE_DRAG_TRACKER = 4;
private class DragTrackerHandler {
private final DragTracker mProxy;
private final float mStartY, mStartX;
private final float mMinDY, mMinDX;
private final float mMaxDY, mMaxDX;
private float mCurrStretchY, mCurrStretchX;
private int mSX, mSY;
public DragTrackerHandler(float x, float y, DragTracker proxy) {
mProxy = proxy;
int docBottom = computeVerticalScrollRange() + getTitleHeight();
int viewTop = getScrollY();
int viewBottom = viewTop + getHeight();
mStartY = y;
mMinDY = -viewTop;
mMaxDY = docBottom - viewBottom;
if (DebugFlags.DRAG_TRACKER || DEBUG_DRAG_TRACKER) {
Log.d(DebugFlags.DRAG_TRACKER_LOGTAG, " dragtracker y= " + y +
" up/down= " + mMinDY + " " + mMaxDY);
=======
private class ScaleDetectorListener implements
ScaleGestureDetector.OnScaleGestureListener {
public boolean onScaleBegin(ScaleGestureDetector detector) {
// cancel the single touch handling
cancelTouch();
if (mZoomButtonsController.isVisible()) {
mZoomButtonsController.setVisible(false);
}
// reset the zoom overview mode so that the page won't auto grow
mInZoomOverview = false;
// If it is in password mode, turn it off so it does not draw
// misplaced.
if (inEditingMode() && nativeFocusCandidateIsPassword()) {
mWebTextView.setInPassword(false);
>>>>>>> 3648f949ef100668500c9f21d0e8b53d310a393e
}
int docRight = computeHorizontalScrollRange();
Solution content
private static final float MAX_SLOPE_FOR_DIAG = 1.5f;
private static final int MIN_BREAK_SNAP_CROSS_DISTANCE = 80;
private static int sign(float x) {
return x > 0 ? 1 : (x < 0 ? -1 : 0);
}
// if the page can scroll <= this value, we won't allow the drag tracker
// to have any effect.
private static final int MIN_SCROLL_AMOUNT_TO_DISABLE_DRAG_TRACKER = 4;
private class DragTrackerHandler {
private final DragTracker mProxy;
private final float mStartY, mStartX;
private final float mMinDY, mMinDX;
private final float mMaxDY, mMaxDX;
private float mCurrStretchY, mCurrStretchX;
private int mSX, mSY;
public DragTrackerHandler(float x, float y, DragTracker proxy) {
mProxy = proxy;
int docBottom = computeVerticalScrollRange() + getTitleHeight();
int viewTop = getScrollY();
int viewBottom = viewTop + getHeight();
mStartY = y;
mMinDY = -viewTop;
mMaxDY = docBottom - viewBottom;
if (DebugFlags.DRAG_TRACKER || DEBUG_DRAG_TRACKER) {
Log.d(DebugFlags.DRAG_TRACKER_LOGTAG, " dragtracker y= " + y +
" up/down= " + mMinDY + " " + mMaxDY);
}
int docRight = computeHorizontalScrollRange();
File
WebView.java
Developer's decision
Version 1
Kind of conflict
Attribute
Class signature
Comment
If statement
Method declaration
Method invocation
Method signature
Variable
Chunk
Conflicting content
mInZoomOverview = !mInZoomOverview;
// remove the zoom control after double tap
WebSettings settings = getSettings();
<<<<<<< HEAD
if (settings.getBuiltInZoomControls()) {
if (mZoomButtonsController.isVisible()) {
mZoomButtonsController.setVisible(false);
}
} else {
if (mZoomControlRunnable != null) {
mPrivateHandler.removeCallbacks(mZoomControlRunnable);
=======
// remove the zoom control after double tap
if (settings.getBuiltInZoomControls()) {
if (mZoomButtonsController.isVisible()) {
mZoomButtonsController.setVisible(false);
}
} else {
if (mZoomControlRunnable != null) {
mPrivateHandler.removeCallbacks(mZoomControlRunnable);
}
if (mZoomControls != null) {
mZoomControls.hide();
}
}
settings.setDoubleTapToastCount(0);
if ((settings.getLayoutAlgorithm() == WebSettings.LayoutAlgorithm.NARROW_COLUMNS)
&& (Math.abs(mActualScale - mTextWrapScale) >= 0.01f)) {
setNewZoomScale(mActualScale, true, true);
float overviewScale = (float) getViewWidth() / mZoomOverviewWidth;
if (Math.abs(mActualScale - overviewScale) < 0.01f) {
mInZoomOverview = true;
>>>>>>> 3648f949ef100668500c9f21d0e8b53d310a393e
}
if (mZoomControls != null) {
mZoomControls.hide();
Solution content
// one.
}
mInZoomOverview = !mInZoomOverview;
// remove the zoom control after double tap
WebSettings settings = getSettings();
if (settings.getBuiltInZoomControls()) {
if (mZoomButtonsController.isVisible()) {
mZoomButtonsController.setVisible(false);
}
} else {
if (mZoomControlRunnable != null) {
mPrivateHandler.removeCallbacks(mZoomControlRunnable);
}
if (mZoomControls != null) {
mZoomControls.hide();
}
}
settings.setDoubleTapToastCount(0);
if (mInZoomOverview) {
float newScale = (float) getViewWidth() / mZoomOverviewWidth;
if (Math.abs(mActualScale - newScale) < 0.01f) {
// reset mInZoomOverview to false if scale doesn't change
mInZoomOverview = false;
} else {
// Force the titlebar fully reveal in overview mode
if (mScrollY < getTitleHeight()) mScrollY = 0;
zoomWithPreview(newScale);
}
} else {
// mLastTouchX and mLastTouchY are the point in the current viewport
int contentX = viewToContentX((int) mLastTouchX + mScrollX);
int contentY = viewToContentY((int) mLastTouchY + mScrollY);
int left = nativeGetBlockLeftEdge(contentX, contentY, mActualScale);
if (left != NO_LEFTEDGE) {
// add a 5pt padding to the left edge. Re-calculate the zoom
// center so that the new scroll x will be on the left edge.
mZoomCenterX = left < 5 ? 0 : (left - 5) * mLastScale
* mActualScale / (mLastScale - mActualScale);
}
zoomWithPreview(mLastScale);
}
}
// Called by JNI to handle a touch on a node representing an email address,
// address, or phone number
private void overrideLoading(String url) {
mCallbackProxy.uiOverrideUrlLoading(url);
}
@Override
public boolean requestFocus(int direction, Rect previouslyFocusedRect) {
boolean result = false;
if (inEditingMode()) {
result = mWebTextView.requestFocus(direction,
previouslyFocusedRect);
} else {
result = super.requestFocus(direction, previouslyFocusedRect);
if (mWebViewCore.getSettings().getNeedInitialFocus()) {
// For cases such as GMail, where we gain focus from a direction,
}
// we want to move to the first available link.
// FIXME: If there are no visible links, we may not want to
int fakeKeyDirection = 0;
switch(direction) {
case View.FOCUS_UP:
fakeKeyDirection = KeyEvent.KEYCODE_DPAD_UP;
break;
case View.FOCUS_DOWN:
fakeKeyDirection = KeyEvent.KEYCODE_DPAD_DOWN;
break;
case View.FOCUS_LEFT:
fakeKeyDirection = KeyEvent.KEYCODE_DPAD_LEFT;
break;
case View.FOCUS_RIGHT:
fakeKeyDirection = KeyEvent.KEYCODE_DPAD_RIGHT;
break;
default:
return result;
}
if (mNativeClass != 0 && !nativeHasCursorNode()) {
navHandledKey(fakeKeyDirection, 1, true, 0, true);
}
}
}
return result;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int measuredHeight = heightSize;
int measuredWidth = widthSize;
// Grab the content size from WebViewCore.
int contentHeight = contentToViewDimension(mContentHeight);
int contentWidth = contentToViewDimension(mContentWidth);
// Log.d(LOGTAG, "------- measure " + heightMode);
if (heightMode != MeasureSpec.EXACTLY) {
mHeightCanMeasure = true;
measuredHeight = contentHeight;
if (heightMode == MeasureSpec.AT_MOST) {
// If we are larger than the AT_MOST height, then our height can
// no longer be measured and we should scroll internally.
if (measuredHeight > heightSize) {
measuredHeight = heightSize;
mHeightCanMeasure = false;
}
}
} else {
mHeightCanMeasure = false;
}
if (mNativeClass != 0) {
nativeSetHeightCanMeasure(mHeightCanMeasure);
}
// For the width, always use the given size unless unspecified.
if (widthMode == MeasureSpec.UNSPECIFIED) {
mWidthCanMeasure = true;
measuredWidth = contentWidth;
} else {
mWidthCanMeasure = false;
}
synchronized (this) {
setMeasuredDimension(measuredWidth, measuredHeight);
}
}
@Override
public boolean requestChildRectangleOnScreen(View child,
Rect rect,
boolean immediate) {
rect.offset(child.getLeft() - child.getScrollX(),
child.getTop() - child.getScrollY());
int height = getViewHeightWithTitle();
int screenTop = mScrollY;
int screenBottom = screenTop + height;
int scrollYDelta = 0;
if (rect.bottom > screenBottom) {
int oneThirdOfScreenHeight = height / 3;
if (rect.height() > 2 * oneThirdOfScreenHeight) {
// If the rectangle is too tall to fit in the bottom two thirds
// of the screen, place it at the top.
scrollYDelta = rect.top - screenTop;
} else {
// If the rectangle will still fit on screen, we want its
// top to be in the top third of the screen.
scrollYDelta = rect.top - (screenTop + oneThirdOfScreenHeight);
}
} else if (rect.top < screenTop) {
scrollYDelta = rect.top - screenTop;
}
int width = getWidth() - getVerticalScrollbarWidth();
int screenLeft = mScrollX;
int screenRight = screenLeft + width;
int scrollXDelta = 0;
if (rect.right > screenRight && rect.left > screenLeft) {
if (rect.width() > width) {
scrollXDelta += (rect.left - screenLeft);
} else {
scrollXDelta += (rect.right - screenRight);
}
} else if (rect.left < screenLeft) {
scrollXDelta -= (screenLeft - rect.left);
}
if ((scrollYDelta | scrollXDelta) != 0) {
return pinScrollBy(scrollXDelta, scrollYDelta, !immediate, 0);
}
return false;
}
/* package */ void replaceTextfieldText(int oldStart, int oldEnd,
String replace, int newStart, int newEnd) {
WebViewCore.ReplaceTextData arg = new WebViewCore.ReplaceTextData();
arg.mReplace = replace;
arg.mNewStart = newStart;
arg.mNewEnd = newEnd;
mTextGeneration++;
arg.mTextGeneration = mTextGeneration;
mWebViewCore.sendMessage(EventHub.REPLACE_TEXT, oldStart, oldEnd, arg);
}
/* package */ void passToJavaScript(String currentText, KeyEvent event) {
WebViewCore.JSKeyData arg = new WebViewCore.JSKeyData();
arg.mEvent = event;
arg.mCurrentText = currentText;
// Increase our text generation number, and pass it to webcore thread
mTextGeneration++;
mWebViewCore.sendMessage(EventHub.PASS_TO_JS, mTextGeneration, 0, arg);
// WebKit's document state is not saved until about to leave the page.
// To make sure the host application, like Browser, has the up to date
// document state when it goes to background, we force to save the
// document state.
mWebViewCore.removeMessages(EventHub.SAVE_DOCUMENT_STATE);
mWebViewCore.sendMessageDelayed(EventHub.SAVE_DOCUMENT_STATE,
cursorData(), 1000);
}
/* package */ WebViewCore getWebViewCore() {
return mWebViewCore;
}
//-------------------------------------------------------------------------
// Methods can be called from a separate thread, like WebViewCore
// If it needs to call the View system, it has to send message.
//-------------------------------------------------------------------------
/**
* General handler to receive message coming from webkit thread
*/
class PrivateHandler extends Handler {
@Override
public void handleMessage(Message msg) {
// exclude INVAL_RECT_MSG_ID since it is frequently output
if (DebugFlags.WEB_VIEW && msg.what != INVAL_RECT_MSG_ID) {
Log.v(LOGTAG, msg.what < REMEMBER_PASSWORD || msg.what
> RETURN_LABEL ? Integer.toString(msg.what)
: HandlerDebugString[msg.what - REMEMBER_PASSWORD]);
}
if (mWebViewCore == null) {
// after WebView's destroy() is called, skip handling messages.
return;
}
switch (msg.what) {
case REMEMBER_PASSWORD: {
mDatabase.setUsernamePassword(
msg.getData().getString("host"),
msg.getData().getString("username"),
msg.getData().getString("password"));
((Message) msg.obj).sendToTarget();
break;
}
case NEVER_REMEMBER_PASSWORD: {
mDatabase.setUsernamePassword(
msg.getData().getString("host"), null, null);
((Message) msg.obj).sendToTarget();
break;
}
case SWITCH_TO_SHORTPRESS: {
// if mPreventDrag is not confirmed, treat it as no so that
// it won't block panning the page.
if (mPreventDrag == PREVENT_DRAG_MAYBE_YES) {
mPreventDrag = PREVENT_DRAG_NO;
mPreventLongPress = false;
mPreventDoubleTap = false;
}
if (mTouchMode == TOUCH_INIT_MODE) {
mTouchMode = mFullScreenHolder == null
? TOUCH_SHORTPRESS_START_MODE
: TOUCH_SHORTPRESS_MODE;
updateSelection();
} else if (mTouchMode == TOUCH_DOUBLE_TAP_MODE) {
mTouchMode = TOUCH_DONE_MODE;
}
break;
}
case SWITCH_TO_LONGPRESS: {
if (mPreventLongPress) {
mTouchMode = TOUCH_DONE_MODE;
WebViewCore.TouchEventData ted
= new WebViewCore.TouchEventData();
ted.mAction = WebViewCore.ACTION_LONGPRESS;
ted.mX = viewToContentX((int) mLastTouchX + mScrollX);
ted.mY = viewToContentY((int) mLastTouchY + mScrollY);
mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted);
} else if (mPreventDrag == PREVENT_DRAG_NO) {
mTouchMode = TOUCH_DONE_MODE;
if (mFullScreenHolder == null) {
performLongClick();
rebuildWebTextView();
}
}
break;
}
case RELEASE_SINGLE_TAP: {
if (mPreventDrag == PREVENT_DRAG_NO) {
mTouchMode = TOUCH_DONE_MODE;
doShortPress();
}
break;
}
case SCROLL_BY_MSG_ID:
setContentScrollBy(msg.arg1, msg.arg2, (Boolean) msg.obj);
break;
case SYNC_SCROLL_TO_MSG_ID:
if (mUserScroll) {
// if user has scrolled explicitly, don't sync the
// scroll position any more
mUserScroll = false;
break;
}
// fall through
case SCROLL_TO_MSG_ID:
if (setContentScrollTo(msg.arg1, msg.arg2)) {
// if we can't scroll to the exact position due to pin,
// send a message to WebCore to re-scroll when we get a
// new picture
mUserScroll = false;
mWebViewCore.sendMessage(EventHub.SYNC_SCROLL,
msg.arg1, msg.arg2);
break;
case SPAWN_SCROLL_TO_MSG_ID:
spawnContentScrollTo(msg.arg1, msg.arg2);
break;
case NEW_PICTURE_MSG_ID: {
WebSettings settings = mWebViewCore.getSettings();
// called for new content
final int viewWidth = getViewWidth();
final WebViewCore.DrawData draw =
(WebViewCore.DrawData) msg.obj;
final Point viewSize = draw.mViewPoint;
boolean useWideViewport = settings.getUseWideViewPort();
WebViewCore.RestoreState restoreState = draw.mRestoreState;
boolean hasRestoreState = restoreState != null;
if (hasRestoreState) {
mInZoomOverview = false;
mLastScale = mInitialScaleInPercent > 0
? mInitialScaleInPercent / 100.0f
: restoreState.mTextWrapScale;
if (restoreState.mMinScale == 0) {
if (restoreState.mMobileSite) {
if (draw.mMinPrefWidth >
Math.max(0, draw.mViewPoint.x)) {
mMinZoomScale = (float) viewWidth
/ draw.mMinPrefWidth;
mMinZoomScaleFixed = false;
} else {
mMinZoomScale = restoreState.mDefaultScale;
mMinZoomScaleFixed = true;
}
} else {
mMinZoomScale = DEFAULT_MIN_ZOOM_SCALE;
mMinZoomScaleFixed = false;
}
} else {
mMinZoomScale = restoreState.mMinScale;
mMinZoomScaleFixed = true;
}
if (restoreState.mMaxScale == 0) {
mMaxZoomScale = DEFAULT_MAX_ZOOM_SCALE;
} else {
mMaxZoomScale = restoreState.mMaxScale;
}
setNewZoomScale(mLastScale, false);
setContentScrollTo(restoreState.mScrollX,
restoreState.mScrollY);
if (useWideViewport
&& settings.getLoadWithOverviewMode()) {
if (restoreState.mViewScale == 0
|| (restoreState.mMobileSite
&& mMinZoomScale < restoreState.mDefaultScale)) {
mInZoomOverview = true;
}
}
// As we are on a new page, remove the WebTextView. This
// is necessary for page loads driven by webkit, and in
// particular when the user was on a password field, so
// the WebTextView was visible.
clearTextEntry();
// update the zoom buttons as the scale can be changed
if (getSettings().getBuiltInZoomControls()) {
updateZoomButtonsEnabled();
}
}
// We update the layout (i.e. request a layout from the
// view system) if the last view size that we sent to
// WebCore matches the view size of the picture we just
// received in the fixed dimension.
final boolean updateLayout = viewSize.x == mLastWidthSent
&& viewSize.y == mLastHeightSent;
recordNewContentSize(draw.mWidthHeight.x,
draw.mWidthHeight.y
+ (mFindIsUp ? mFindHeight : 0), updateLayout);
if (DebugFlags.WEB_VIEW) {
Rect b = draw.mInvalRegion.getBounds();
Log.v(LOGTAG, "NEW_PICTURE_MSG_ID {" +
b.left+","+b.top+","+b.right+","+b.bottom+"}");
}
invalidateContentRect(draw.mInvalRegion.getBounds());
if (mPictureListener != null) {
mPictureListener.onNewPicture(WebView.this, capturePicture());
}
if (useWideViewport) {
// limit mZoomOverviewWidth to sMaxViewportWidth so that
// if the page doesn't behave well, the WebView won't go
// insane.
mZoomOverviewWidth = Math.min(sMaxViewportWidth, Math
.max(draw.mMinPrefWidth, draw.mViewPoint.x));
}
if (!mMinZoomScaleFixed) {
mMinZoomScale = (float) viewWidth / mZoomOverviewWidth;
}
if (!mDrawHistory && mInZoomOverview) {
// fit the content width to the current view. Ignore
// the rounding error case.
if (Math.abs((viewWidth * mInvActualScale)
- mZoomOverviewWidth) > 1) {
setNewZoomScale((float) viewWidth
/ mZoomOverviewWidth, false);
}
}
if (draw.mFocusSizeChanged && inEditingMode()) {
mFocusSizeChanged = true;
}
if (hasRestoreState) {
mViewManager.postReadyToDrawAll();
}
break;
}
case WEBCORE_INITIALIZED_MSG_ID:
// nativeCreate sets mNativeClass to a non-zero value
nativeCreate(msg.arg1);
break;
case UPDATE_TEXTFIELD_TEXT_MSG_ID:
// Make sure that the textfield is currently focused
// and representing the same node as the pointer.
if (inEditingMode() &&
mWebTextView.isSameTextField(msg.arg1)) {
if (msg.getData().getBoolean("password")) {
Spannable text = (Spannable) mWebTextView.getText();
int start = Selection.getSelectionStart(text);
int end = Selection.getSelectionEnd(text);
mWebTextView.setInPassword(true);
// Restore the selection, which may have been
// ruined by setInPassword.
Spannable pword =
(Spannable) mWebTextView.getText();
Selection.setSelection(pword, start, end);
// If the text entry has created more events, ignore
// this one.
} else if (msg.arg2 == mTextGeneration) {
mWebTextView.setTextAndKeepSelection(
(String) msg.obj);
}
}
break;
case UPDATE_TEXT_SELECTION_MSG_ID:
if (inEditingMode()
&& mWebTextView.isSameTextField(msg.arg1)
&& msg.arg2 == mTextGeneration) {
WebViewCore.TextSelectionData tData
= (WebViewCore.TextSelectionData) msg.obj;
mWebTextView.setSelectionFromWebKit(tData.mStart,
tData.mEnd);
}
break;
case RETURN_LABEL:
if (inEditingMode()
&& mWebTextView.isSameTextField(msg.arg1)) {
mWebTextView.setHint((String) msg.obj);
InputMethodManager imm
= InputMethodManager.peekInstance();
// The hint is propagated to the IME in
// onCreateInputConnection. If the IME is already
// active, restart it so that its hint text is updated.
if (imm != null && imm.isActive(mWebTextView)) {
imm.restartInput(mWebTextView);
}
}
break;
case MOVE_OUT_OF_PLUGIN:
navHandledKey(msg.arg1, 1, false, 0, true);
break;
case UPDATE_TEXT_ENTRY_MSG_ID:
// this is sent after finishing resize in WebViewCore. Make
// sure the text edit box is still on the screen.
if (inEditingMode() && nativeCursorIsTextInput()) {
mWebTextView.bringIntoView();
rebuildWebTextView();
}
break;
case CLEAR_TEXT_ENTRY:
clearTextEntry();
break;
case INVAL_RECT_MSG_ID: {
Rect r = (Rect)msg.obj;
if (r == null) {
invalidate();
} else {
// we need to scale r from content into view coords,
// which viewInvalidate() does for us
viewInvalidate(r.left, r.top, r.right, r.bottom);
}
break;
}
case IMMEDIATE_REPAINT_MSG_ID: {
int updates = msg.arg1;
if (updates != 0) {
// updates is a C++ pointer to a Vector of
// AnimationValues that we apply to the layers.
// The Vector is deallocated in nativeUpdateLayers().
nativeUpdateLayers(mRootLayer, updates);
}
invalidate();
break;
}
case SET_ROOT_LAYER_MSG_ID: {
int oldLayer = mRootLayer;
mRootLayer = msg.arg1;
if (oldLayer > 0) {
nativeDestroyLayer(oldLayer);
}
if (mRootLayer == 0) {
mLayersHaveAnimations = false;
}
if (mEvaluateThread != null) {
mEvaluateThread.cancel();
mEvaluateThread = null;
}
if (nativeLayersHaveAnimations(mRootLayer)) {
mLayersHaveAnimations = true;
mEvaluateThread = new EvaluateLayersAnimations();
mEvaluateThread.start();
}
invalidate();
break;
}
case REQUEST_FORM_DATA:
AutoCompleteAdapter adapter = (AutoCompleteAdapter) msg.obj;
if (mWebTextView.isSameTextField(msg.arg1)) {
mWebTextView.setAdapterCustom(adapter);
}
break;
case RESUME_WEBCORE_UPDATE:
WebViewCore.resumeUpdate(mWebViewCore);
break;
case LONG_PRESS_CENTER:
// as this is shared by keydown and trackballdown, reset all
// the states
mGotCenterDown = false;
mTrackballDown = false;
// LONG_PRESS_CENTER is sent as a delayed message. If we
// switch to windows overview, the WebView will be
// temporarily removed from the view system. In that case,
// do nothing.
if (getParent() != null) {
performLongClick();
}
break;
case WEBCORE_NEED_TOUCH_EVENTS:
mForwardTouchEvents = (msg.arg1 != 0);
break;
case PREVENT_TOUCH_ID:
if (msg.arg1 == MotionEvent.ACTION_DOWN) {
// dont override if mPreventDrag has been set to no due
// to time out
if (mPreventDrag == PREVENT_DRAG_MAYBE_YES) {
mPreventDrag = (msg.arg2 & TOUCH_PREVENT_DRAG)
== TOUCH_PREVENT_DRAG ? PREVENT_DRAG_YES
: PREVENT_DRAG_NO;
if (mPreventDrag == PREVENT_DRAG_YES) {
mTouchMode = TOUCH_DONE_MODE;
} else {
mPreventLongPress =
(msg.arg2 & TOUCH_PREVENT_LONGPRESS)
== TOUCH_PREVENT_LONGPRESS;
mPreventDoubleTap =
(msg.arg2 & TOUCH_PREVENT_DOUBLETAP)
== TOUCH_PREVENT_DOUBLETAP;
}
}
}
break;
case REQUEST_KEYBOARD:
if (msg.arg1 == 0) {
hideSoftKeyboard();
} else {
displaySoftKeyboard(1 == msg.arg2);
}
break;
case FIND_AGAIN:
// Ignore if find has been dismissed.
if (mFindIsUp) {
findAll(mLastFind);
}
break;
case DRAG_HELD_MOTIONLESS:
mHeldMotionless = MOTIONLESS_TRUE;
invalidate();
// fall through to keep scrollbars awake
case AWAKEN_SCROLL_BARS:
if (mTouchMode == TOUCH_DRAG_MODE
&& mHeldMotionless == MOTIONLESS_TRUE) {
awakenScrollBars(ViewConfiguration
.getScrollDefaultDelay(), false);
mPrivateHandler.sendMessageDelayed(mPrivateHandler
.obtainMessage(AWAKEN_SCROLL_BARS),
ViewConfiguration.getScrollDefaultDelay());
}
break;
case DO_MOTION_UP:
doMotionUp(msg.arg1, msg.arg2);
break;
case SHOW_FULLSCREEN:
WebViewCore.PluginFullScreenData data
= (WebViewCore.PluginFullScreenData) msg.obj;
if (data.mNpp != 0 && data.mView != null) {
if (mFullScreenHolder != null) {
Log.w(LOGTAG,
"Should not have another full screen.");
mFullScreenHolder.dismiss();
}
mFullScreenHolder = new PluginFullScreenHolder(
WebView.this, data.mNpp);
mFullScreenHolder.setContentView(data.mView);
mFullScreenHolder.setCancelable(false);
mFullScreenHolder.setCanceledOnTouchOutside(false);
mFullScreenHolder.show();
}
// move the matching embedded view fully into the view so
// that touch will be valid instead of rejected due to out
// of the visible bounds
// TODO: do we need to preserve the original position and
// scale so that we can revert it when leaving the full
// screen mode?
int x = contentToViewX(data.mDocX);
int y = contentToViewY(data.mDocY);
int width = contentToViewDimension(data.mDocWidth);
int height = contentToViewDimension(data.mDocHeight);
int viewWidth = getViewWidth();
int viewHeight = getViewHeight();
int newX = mScrollX;
int newY = mScrollY;
if (x < mScrollX) {
newX = x + (width > viewWidth
? (width - viewWidth) / 2 : 0);
} else if (x + width > mScrollX + viewWidth) {
newX = x + width - viewWidth - (width > viewWidth
? (width - viewWidth) / 2 : 0);
}
if (y < mScrollY) {
newY = y + (height > viewHeight
? (height - viewHeight) / 2 : 0);
} else if (y + height > mScrollY + viewHeight) {
newY = y + height - viewHeight - (height > viewHeight
? (height - viewHeight) / 2 : 0);
}
scrollTo(newX, newY);
if (width > viewWidth || height > viewHeight) {
mZoomCenterX = viewWidth * .5f;
mZoomCenterY = viewHeight * .5f;
setNewZoomScale(mActualScale
/ Math.max((float) width / viewWidth,
(float) height / viewHeight), false);
}
// Now update the bound
mFullScreenHolder.updateBound(contentToViewX(data.mDocX)
- mScrollX, contentToViewY(data.mDocY) - mScrollY,
contentToViewDimension(data.mDocWidth),
contentToViewDimension(data.mDocHeight));
break;
case HIDE_FULLSCREEN:
if (mFullScreenHolder != null) {
mFullScreenHolder.dismiss();
mFullScreenHolder = null;
}
break;
case DOM_FOCUS_CHANGED:
if (inEditingMode()) {
nativeClearCursor();
rebuildWebTextView();
}
break;
default:
super.handleMessage(msg);
break;
}
}
}
// Class used to use a dropdown for a