Loading core/java/android/webkit/AutoCompletePopup.java 0 → 100644 +264 −0 Original line number Original line Diff line number Diff line /* * Copyright (C) 2012 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.webkit; import android.content.Context; import android.graphics.Rect; import android.os.Handler; import android.os.Message; import android.text.Editable; import android.util.Log; import android.view.KeyEvent; import android.view.View; import android.widget.AbsoluteLayout; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.Filter; import android.widget.Filterable; import android.widget.ListAdapter; import android.widget.ListPopupWindow; class AutoCompletePopup implements OnItemClickListener, Filter.FilterListener { private static class AnchorView extends View { AnchorView(Context context) { super(context); setFocusable(false); } } private static final int AUTOFILL_FORM = 100; private boolean mIsAutoFillProfileSet; private Handler mHandler; private int mQueryId; private Rect mNodeBounds = new Rect(); private int mNodeLayerId; private ListPopupWindow mPopup; private Filter mFilter; private CharSequence mText; private ListAdapter mAdapter; private boolean mIsFocused; private View mAnchor; private WebViewClassic.WebViewInputConnection mInputConnection; private WebViewClassic mWebView; public AutoCompletePopup(Context context, WebViewClassic webView, WebViewClassic.WebViewInputConnection inputConnection) { mInputConnection = inputConnection; mWebView = webView; mPopup = new ListPopupWindow(context); mAnchor = new AnchorView(context); mWebView.getWebView().addView(mAnchor); mPopup.setOnItemClickListener(this); mPopup.setAnchorView(mAnchor); mPopup.setPromptPosition(ListPopupWindow.POSITION_PROMPT_BELOW); mHandler = new Handler() { @Override public void handleMessage(Message msg) { switch (msg.what) { case AUTOFILL_FORM: mWebView.autoFillForm(mQueryId); break; } } }; } public boolean onKeyPreIme(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK && mPopup.isShowing()) { // special case for the back key, we do not even try to send it // to the drop down list but instead, consume it immediately if (event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0) { KeyEvent.DispatcherState state = mAnchor.getKeyDispatcherState(); if (state != null) { state.startTracking(event, this); } return true; } else if (event.getAction() == KeyEvent.ACTION_UP) { KeyEvent.DispatcherState state = mAnchor.getKeyDispatcherState(); if (state != null) { state.handleUpEvent(event); } if (event.isTracking() && !event.isCanceled()) { Log.v("AutoCompletePopup", "dismiss popup 2"); mPopup.dismiss(); return true; } } } if (mPopup.isShowing()) { return mPopup.onKeyPreIme(keyCode, event); } return false; } public void setFocused(boolean isFocused) { mIsFocused = isFocused; if (!mIsFocused) { Log.v("AutoCompletePopup", "dismiss popup 3"); mPopup.dismiss(); } } public void setText(CharSequence text) { mText = text; if (mFilter != null) { mFilter.filter(text, this); } } public void setAutoFillQueryId(int queryId) { mQueryId = queryId; } public void clearAdapter() { mAdapter = null; mFilter = null; Log.v("AutoCompletePopup", "dismiss popup 4"); mPopup.dismiss(); mPopup.setAdapter(null); } public <T extends ListAdapter & Filterable> void setAdapter(T adapter) { mPopup.setAdapter(adapter); mAdapter = adapter; if (adapter != null) { mFilter = adapter.getFilter(); mFilter.filter(mText, this); } else { mFilter = null; } resetRect(); } public void setNodeBounds(Rect nodeBounds, int layerId) { mNodeBounds.set(nodeBounds); mNodeLayerId = layerId; resetRect(); } public void resetRect() { Log.v("AutoCompletePopup", "resetRect: " + mNodeBounds); int left = mWebView.contentToViewX(mNodeBounds.left); int right = mWebView.contentToViewX(mNodeBounds.right); int width = right - left; mPopup.setWidth(width); int bottom = mWebView.contentToViewY(mNodeBounds.bottom); int top = mWebView.contentToViewY(mNodeBounds.top); int height = bottom - top; AbsoluteLayout.LayoutParams lp = (AbsoluteLayout.LayoutParams) mAnchor.getLayoutParams(); boolean needsUpdate = false; if (null == lp) { lp = new AbsoluteLayout.LayoutParams(width, height, left, top); } else { if ((lp.x != left) || (lp.y != top) || (lp.width != width) || (lp.height != height)) { needsUpdate = true; lp.x = left; lp.y = top; lp.width = width; lp.height = height; } } Log.v("AutoCompletePopup", "resetRect layout " + lp.x + ", " + lp.y + ", " + lp.width + ", " + lp.height); if (needsUpdate) { mAnchor.setLayoutParams(lp); } if (mPopup.isShowing()) { Log.v("AutoCompletePopup", "showing popup again"); mPopup.show(); // update its position } } public void scrollDelta(int layerId, int dx, int dy) { if (layerId == mNodeLayerId) { mNodeBounds.offset(dx, dy); resetRect(); } } // AdapterView.OnItemClickListener implementation @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { if (id == 0 && position == 0 && mInputConnection.getIsAutoFillable()) { mText = ""; pushTextToInputConnection(); // Blank out the text box while we wait for WebCore to fill the form. if (mIsAutoFillProfileSet) { // Call a webview method to tell WebCore to autofill the form. mWebView.autoFillForm(mQueryId); } else { // There is no autofill profile setup yet and the user has // elected to try and set one up. Call through to the // embedder to action that. mWebView.getWebChromeClient().setupAutoFill( mHandler.obtainMessage(AUTOFILL_FORM)); } } else { Object selectedItem; if (position < 0) { selectedItem = mPopup.getSelectedItem(); } else { selectedItem = mAdapter.getItem(position); } if (selectedItem != null) { setText(mFilter.convertResultToString(selectedItem)); pushTextToInputConnection(); } } Log.v("AutoCompletePopup", "dismiss popup 5"); mPopup.dismiss(); } public void setIsAutoFillProfileSet(boolean isAutoFillProfileSet) { mIsAutoFillProfileSet = isAutoFillProfileSet; } private void pushTextToInputConnection() { Editable oldText = mInputConnection.getEditable(); mInputConnection.setSelection(0, oldText.length()); mInputConnection.replaceSelection(mText); mInputConnection.setSelection(mText.length(), mText.length()); } @Override public void onFilterComplete(int count) { if (!mIsFocused) { Log.v("AutoCompletePopup", "dismiss popup 1"); mPopup.dismiss(); return; } boolean showDropDown = (count > 0) && (mInputConnection.getIsAutoFillable() || mText.length() > 0); if (showDropDown) { if (!mPopup.isShowing()) { // Make sure the list does not obscure the IME when shown for the first time. mPopup.setInputMethodMode(ListPopupWindow.INPUT_METHOD_NEEDED); } Log.v("AutoCompletePopup", "showing popup"); mPopup.show(); mPopup.getListView().setOverScrollMode(View.OVER_SCROLL_ALWAYS); } else { Log.v("AutoCompletePopup", "dismiss popup"); mPopup.dismiss(); } } } core/java/android/webkit/WebViewClassic.java +188 −8 Original line number Original line Diff line number Diff line Loading @@ -375,7 +375,7 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc * InputConnection used for ContentEditable. This captures changes * InputConnection used for ContentEditable. This captures changes * to the text and sends them either as key strokes or text changes. * to the text and sends them either as key strokes or text changes. */ */ private class WebViewInputConnection extends BaseInputConnection { class WebViewInputConnection extends BaseInputConnection { // Used for mapping characters to keys typed. // Used for mapping characters to keys typed. private KeyCharacterMap mKeyCharacterMap; private KeyCharacterMap mKeyCharacterMap; private boolean mIsKeySentByMe; private boolean mIsKeySentByMe; Loading @@ -383,11 +383,31 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc private int mImeOptions; private int mImeOptions; private String mHint; private String mHint; private int mMaxLength; private int mMaxLength; private boolean mIsAutoFillable; private boolean mIsAutoCompleteEnabled; private String mName; public WebViewInputConnection() { public WebViewInputConnection() { super(mWebView, true); super(mWebView, true); } } public void setAutoFillable(int queryId) { mIsAutoFillable = getSettings().getAutoFillEnabled() && (queryId != WebTextView.FORM_NOT_AUTOFILLABLE); int variation = mInputType & EditorInfo.TYPE_MASK_VARIATION; if (variation != EditorInfo.TYPE_TEXT_VARIATION_WEB_PASSWORD && (mIsAutoFillable || mIsAutoCompleteEnabled)) { if (mName != null && mName.length() > 0) { requestFormData(mName, mFieldPointer, mIsAutoFillable, mIsAutoCompleteEnabled); } } } public boolean getIsAutoFillable() { return mIsAutoFillable; } @Override @Override public boolean sendKeyEvent(KeyEvent event) { public boolean sendKeyEvent(KeyEvent event) { // Some IMEs send key events directly using sendKeyEvents. // Some IMEs send key events directly using sendKeyEvents. Loading Loading @@ -582,6 +602,9 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc mInputType = inputType; mInputType = inputType; mImeOptions = imeOptions; mImeOptions = imeOptions; mMaxLength = initData.mMaxLength; mMaxLength = initData.mMaxLength; mIsAutoCompleteEnabled = initData.mIsAutoCompleteEnabled; mName = initData.mName; mAutoCompletePopup.clearAdapter(); } } public void setupEditorInfo(EditorInfo outAttrs) { public void setupEditorInfo(EditorInfo outAttrs) { Loading Loading @@ -629,6 +652,13 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc REPLACE_TEXT, start, end, text.toString()); REPLACE_TEXT, start, end, text.toString()); mPrivateHandler.sendMessage(replaceMessage); mPrivateHandler.sendMessage(replaceMessage); } } if (mAutoCompletePopup != null) { StringBuilder newText = new StringBuilder(); newText.append(editable.subSequence(0, start)); newText.append(text); newText.append(editable.subSequence(end, editable.length())); mAutoCompletePopup.setText(newText.toString()); } mIsKeySentByMe = false; mIsKeySentByMe = false; } } Loading Loading @@ -795,6 +825,7 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc WebViewInputConnection mInputConnection = null; WebViewInputConnection mInputConnection = null; private int mFieldPointer; private int mFieldPointer; private PastePopupWindow mPasteWindow; private PastePopupWindow mPasteWindow; AutoCompletePopup mAutoCompletePopup; private static class OnTrimMemoryListener implements ComponentCallbacks2 { private static class OnTrimMemoryListener implements ComponentCallbacks2 { private static OnTrimMemoryListener sInstance = null; private static OnTrimMemoryListener sInstance = null; Loading Loading @@ -1104,6 +1135,7 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc private static final int SWITCH_TO_SHORTPRESS = 3; private static final int SWITCH_TO_SHORTPRESS = 3; private static final int SWITCH_TO_LONGPRESS = 4; private static final int SWITCH_TO_LONGPRESS = 4; private static final int RELEASE_SINGLE_TAP = 5; private static final int RELEASE_SINGLE_TAP = 5; private static final int REQUEST_FORM_DATA = 6; private static final int DRAG_HELD_MOTIONLESS = 8; private static final int DRAG_HELD_MOTIONLESS = 8; private static final int AWAKEN_SCROLL_BARS = 9; private static final int AWAKEN_SCROLL_BARS = 9; private static final int PREVENT_DEFAULT_TIMEOUT = 10; private static final int PREVENT_DEFAULT_TIMEOUT = 10; Loading Loading @@ -1156,6 +1188,9 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc static final int REPLACE_TEXT = 143; static final int REPLACE_TEXT = 143; static final int CLEAR_CARET_HANDLE = 144; static final int CLEAR_CARET_HANDLE = 144; static final int KEY_PRESS = 145; static final int KEY_PRESS = 145; static final int RELOCATE_AUTO_COMPLETE_POPUP = 146; static final int FOCUS_NODE_CHANGED = 147; static final int AUTOFILL_FORM = 148; private static final int FIRST_PACKAGE_MSG_ID = SCROLL_TO_MSG_ID; private static final int FIRST_PACKAGE_MSG_ID = SCROLL_TO_MSG_ID; private static final int LAST_PACKAGE_MSG_ID = HIT_TEST_RESULT; private static final int LAST_PACKAGE_MSG_ID = HIT_TEST_RESULT; Loading Loading @@ -3560,7 +3595,9 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc @Override @Override public void clearFormData() { public void clearFormData() { checkThread(); checkThread(); // TODO: Implement b/6083041 if (mAutoCompletePopup != null) { mAutoCompletePopup.clearAdapter(); } } } /** /** Loading Loading @@ -3861,12 +3898,12 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc } } private void scrollLayerTo(int x, int y) { private void scrollLayerTo(int x, int y) { if (x == mScrollingLayerRect.left && y == mScrollingLayerRect.top) { int dx = mScrollingLayerRect.left - x; int dy = mScrollingLayerRect.top - y; if (dx == 0 && y == 0) { return; return; } } if (mSelectingText) { if (mSelectingText) { int dx = mScrollingLayerRect.left - x; int dy = mScrollingLayerRect.top - y; if (mSelectCursorBaseLayerId == mCurrentScrollingLayerId) { if (mSelectCursorBaseLayerId == mCurrentScrollingLayerId) { mSelectCursorBase.offset(dx, dy); mSelectCursorBase.offset(dx, dy); } } Loading @@ -3874,6 +3911,9 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc mSelectCursorExtent.offset(dx, dy); mSelectCursorExtent.offset(dx, dy); } } } } if (mAutoCompletePopup != null) { mAutoCompletePopup.scrollDelta(mCurrentScrollingLayerId, dx, dy); } nativeScrollLayer(mCurrentScrollingLayerId, x, y); nativeScrollLayer(mCurrentScrollingLayerId, x, y); mScrollingLayerRect.left = x; mScrollingLayerRect.left = x; mScrollingLayerRect.top = y; mScrollingLayerRect.top = y; Loading Loading @@ -4726,6 +4766,7 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc } } private void onZoomAnimationEnd() { private void onZoomAnimationEnd() { mPrivateHandler.sendEmptyMessage(RELOCATE_AUTO_COMPLETE_POPUP); } } void onFixedLengthZoomAnimationStart() { void onFixedLengthZoomAnimationStart() { Loading Loading @@ -4880,11 +4921,20 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc public InputConnection onCreateInputConnection(EditorInfo outAttrs) { public InputConnection onCreateInputConnection(EditorInfo outAttrs) { if (mInputConnection == null) { if (mInputConnection == null) { mInputConnection = new WebViewInputConnection(); mInputConnection = new WebViewInputConnection(); mAutoCompletePopup = new AutoCompletePopup(mContext, this, mInputConnection); } } mInputConnection.setupEditorInfo(outAttrs); mInputConnection.setupEditorInfo(outAttrs); return mInputConnection; return mInputConnection; } } private void relocateAutoCompletePopup() { if (mAutoCompletePopup != null) { mAutoCompletePopup.resetRect(); mAutoCompletePopup.setText(mInputConnection.getEditable()); } } /** /** * Called in response to a message from webkit telling us that the soft * Called in response to a message from webkit telling us that the soft * keyboard should be launched. * keyboard should be launched. Loading Loading @@ -4915,6 +4965,91 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc } } } } /** * Called by AutoCompletePopup to find saved form data associated with the * textfield * @param name Name of the textfield. * @param nodePointer Pointer to the node of the textfield, so it can be * compared to the currently focused textfield when the data is * retrieved. * @param autoFillable true if WebKit has determined this field is part of * a form that can be auto filled. * @param autoComplete true if the attribute "autocomplete" is set to true * on the textfield. */ /* package */ void requestFormData(String name, int nodePointer, boolean autoFillable, boolean autoComplete) { if (mWebViewCore.getSettings().getSaveFormData()) { Message update = mPrivateHandler.obtainMessage(REQUEST_FORM_DATA); update.arg1 = nodePointer; RequestFormData updater = new RequestFormData(name, getUrl(), update, autoFillable, autoComplete); Thread t = new Thread(updater); t.start(); } } /* * This class requests an Adapter for the AutoCompletePopup which shows past * entries stored in the database. It is a Runnable so that it can be done * in its own thread, without slowing down the UI. */ private class RequestFormData implements Runnable { private String mName; private String mUrl; private Message mUpdateMessage; private boolean mAutoFillable; private boolean mAutoComplete; private WebSettingsClassic mWebSettings; public RequestFormData(String name, String url, Message msg, boolean autoFillable, boolean autoComplete) { mName = name; mUrl = WebTextView.urlForAutoCompleteData(url); mUpdateMessage = msg; mAutoFillable = autoFillable; mAutoComplete = autoComplete; mWebSettings = getSettings(); } @Override public void run() { ArrayList<String> pastEntries = new ArrayList<String>(); if (mAutoFillable) { // Note that code inside the adapter click handler in AutoCompletePopup depends // on the AutoFill item being at the top of the drop down list. If you change // the order, make sure to do it there too! if (mWebSettings != null && mWebSettings.getAutoFillProfile() != null) { pastEntries.add(mWebView.getResources().getText( com.android.internal.R.string.autofill_this_form).toString() + " " + mAutoFillData.getPreviewString()); mAutoCompletePopup.setIsAutoFillProfileSet(true); } else { // There is no autofill profile set up yet, so add an option that // will invite the user to set their profile up. pastEntries.add(mWebView.getResources().getText( com.android.internal.R.string.setup_autofill).toString()); mAutoCompletePopup.setIsAutoFillProfileSet(false); } } if (mAutoComplete) { pastEntries.addAll(mDatabase.getFormData(mUrl, mName)); } if (pastEntries.size() > 0) { ArrayAdapter<String> adapter = new ArrayAdapter<String>( mContext, com.android.internal.R.layout.web_text_view_dropdown, pastEntries); mUpdateMessage.obj = adapter; mUpdateMessage.sendToTarget(); } } } /** /** * Dump the display tree to "/sdcard/displayTree.txt" * Dump the display tree to "/sdcard/displayTree.txt" * * Loading Loading @@ -4990,6 +5125,13 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc || keyCode == KeyEvent.KEYCODE_NUMPAD_ENTER; || keyCode == KeyEvent.KEYCODE_NUMPAD_ENTER; } } public boolean onKeyPreIme(int keyCode, KeyEvent event) { if (mAutoCompletePopup != null) { return mAutoCompletePopup.onKeyPreIme(keyCode, event); } return false; } @Override @Override public boolean onKeyDown(int keyCode, KeyEvent event) { public boolean onKeyDown(int keyCode, KeyEvent event) { if (DebugFlags.WEB_VIEW) { if (DebugFlags.WEB_VIEW) { Loading Loading @@ -5593,6 +5735,7 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc // However, do not update the base layer as that hasn't changed // However, do not update the base layer as that hasn't changed setNewPicture(mLoadedPicture, false); setNewPicture(mLoadedPicture, false); } } relocateAutoCompletePopup(); } } @Override @Override Loading Loading @@ -8020,6 +8163,12 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc } } break; break; } } case REQUEST_FORM_DATA: if (mFieldPointer == msg.arg1) { ArrayAdapter<String> adapter = (ArrayAdapter<String>)msg.obj; mAutoCompletePopup.setAdapter(adapter); } break; case LONG_PRESS_CENTER: case LONG_PRESS_CENTER: // as this is shared by keydown and trackballdown, reset all // as this is shared by keydown and trackballdown, reset all Loading Loading @@ -8174,6 +8323,11 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc } } break; break; case FOCUS_NODE_CHANGED: if (mAutoCompletePopup != null) { mAutoCompletePopup.setFocused(msg.arg1 == mFieldPointer); } // fall through to HIT_TEST_RESULT case HIT_TEST_RESULT: case HIT_TEST_RESULT: WebKitHitTest hit = (WebKitHitTest) msg.obj; WebKitHitTest hit = (WebKitHitTest) msg.obj; mFocusedNode = hit; mFocusedNode = hit; Loading @@ -8190,11 +8344,20 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc case SET_AUTOFILLABLE: case SET_AUTOFILLABLE: mAutoFillData = (WebViewCore.AutoFillData) msg.obj; mAutoFillData = (WebViewCore.AutoFillData) msg.obj; // TODO: Support (b/6083041) if (mInputConnection != null) { mInputConnection.setAutoFillable(mAutoFillData.getQueryId()); mAutoCompletePopup.setAutoFillQueryId(mAutoFillData.getQueryId()); } break; break; case AUTOFILL_COMPLETE: case AUTOFILL_COMPLETE: // TODO: Support (b/6083041) if (mAutoCompletePopup != null) { ArrayList<String> pastEntries = new ArrayList<String>(); mAutoCompletePopup.setAdapter(new ArrayAdapter<String>( mContext, com.android.internal.R.layout.web_text_view_dropdown, pastEntries)); } break; break; case COPY_TO_CLIPBOARD: case COPY_TO_CLIPBOARD: Loading @@ -8208,6 +8371,11 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc mFieldPointer = initData.mFieldPointer; mFieldPointer = initData.mFieldPointer; mInputConnection.initEditorInfo(initData); mInputConnection.initEditorInfo(initData); mInputConnection.setTextAndKeepSelection(initData.mText); mInputConnection.setTextAndKeepSelection(initData.mText); nativeMapLayerRect(mNativeClass, initData.mNodeLayerId, initData.mNodeBounds); mAutoCompletePopup.setNodeBounds(initData.mNodeBounds, initData.mNodeLayerId); mAutoCompletePopup.setText(mInputConnection.getEditable()); } } break; break; Loading Loading @@ -8236,6 +8404,15 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc mWebViewCore.sendMessage(EventHub.KEY_PRESS, msg.arg1); mWebViewCore.sendMessage(EventHub.KEY_PRESS, msg.arg1); break; break; case RELOCATE_AUTO_COMPLETE_POPUP: relocateAutoCompletePopup(); break; case AUTOFILL_FORM: mWebViewCore.sendMessage(EventHub.AUTOFILL_FORM, msg.arg1, /* unused */0); break; default: default: super.handleMessage(msg); super.handleMessage(msg); break; break; Loading Loading @@ -9019,7 +9196,8 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc } } /*package*/ void autoFillForm(int autoFillQueryId) { /*package*/ void autoFillForm(int autoFillQueryId) { mWebViewCore.sendMessage(EventHub.AUTOFILL_FORM, autoFillQueryId, /* unused */0); mPrivateHandler.obtainMessage(AUTOFILL_FORM, autoFillQueryId, 0) .sendToTarget(); } } /* package */ ViewManager getViewManager() { /* package */ ViewManager getViewManager() { Loading Loading @@ -9169,4 +9347,6 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc private static native int nativeGetHandleLayerId(int instance, int handle, private static native int nativeGetHandleLayerId(int instance, int handle, Rect cursorLocation); Rect cursorLocation); private static native boolean nativeIsBaseFirst(int instance); private static native boolean nativeIsBaseFirst(int instance); private static native void nativeMapLayerRect(int instance, int layerId, Rect rect); } } core/java/android/webkit/WebViewCore.java +20 −8 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
core/java/android/webkit/AutoCompletePopup.java 0 → 100644 +264 −0 Original line number Original line Diff line number Diff line /* * Copyright (C) 2012 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.webkit; import android.content.Context; import android.graphics.Rect; import android.os.Handler; import android.os.Message; import android.text.Editable; import android.util.Log; import android.view.KeyEvent; import android.view.View; import android.widget.AbsoluteLayout; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.Filter; import android.widget.Filterable; import android.widget.ListAdapter; import android.widget.ListPopupWindow; class AutoCompletePopup implements OnItemClickListener, Filter.FilterListener { private static class AnchorView extends View { AnchorView(Context context) { super(context); setFocusable(false); } } private static final int AUTOFILL_FORM = 100; private boolean mIsAutoFillProfileSet; private Handler mHandler; private int mQueryId; private Rect mNodeBounds = new Rect(); private int mNodeLayerId; private ListPopupWindow mPopup; private Filter mFilter; private CharSequence mText; private ListAdapter mAdapter; private boolean mIsFocused; private View mAnchor; private WebViewClassic.WebViewInputConnection mInputConnection; private WebViewClassic mWebView; public AutoCompletePopup(Context context, WebViewClassic webView, WebViewClassic.WebViewInputConnection inputConnection) { mInputConnection = inputConnection; mWebView = webView; mPopup = new ListPopupWindow(context); mAnchor = new AnchorView(context); mWebView.getWebView().addView(mAnchor); mPopup.setOnItemClickListener(this); mPopup.setAnchorView(mAnchor); mPopup.setPromptPosition(ListPopupWindow.POSITION_PROMPT_BELOW); mHandler = new Handler() { @Override public void handleMessage(Message msg) { switch (msg.what) { case AUTOFILL_FORM: mWebView.autoFillForm(mQueryId); break; } } }; } public boolean onKeyPreIme(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK && mPopup.isShowing()) { // special case for the back key, we do not even try to send it // to the drop down list but instead, consume it immediately if (event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0) { KeyEvent.DispatcherState state = mAnchor.getKeyDispatcherState(); if (state != null) { state.startTracking(event, this); } return true; } else if (event.getAction() == KeyEvent.ACTION_UP) { KeyEvent.DispatcherState state = mAnchor.getKeyDispatcherState(); if (state != null) { state.handleUpEvent(event); } if (event.isTracking() && !event.isCanceled()) { Log.v("AutoCompletePopup", "dismiss popup 2"); mPopup.dismiss(); return true; } } } if (mPopup.isShowing()) { return mPopup.onKeyPreIme(keyCode, event); } return false; } public void setFocused(boolean isFocused) { mIsFocused = isFocused; if (!mIsFocused) { Log.v("AutoCompletePopup", "dismiss popup 3"); mPopup.dismiss(); } } public void setText(CharSequence text) { mText = text; if (mFilter != null) { mFilter.filter(text, this); } } public void setAutoFillQueryId(int queryId) { mQueryId = queryId; } public void clearAdapter() { mAdapter = null; mFilter = null; Log.v("AutoCompletePopup", "dismiss popup 4"); mPopup.dismiss(); mPopup.setAdapter(null); } public <T extends ListAdapter & Filterable> void setAdapter(T adapter) { mPopup.setAdapter(adapter); mAdapter = adapter; if (adapter != null) { mFilter = adapter.getFilter(); mFilter.filter(mText, this); } else { mFilter = null; } resetRect(); } public void setNodeBounds(Rect nodeBounds, int layerId) { mNodeBounds.set(nodeBounds); mNodeLayerId = layerId; resetRect(); } public void resetRect() { Log.v("AutoCompletePopup", "resetRect: " + mNodeBounds); int left = mWebView.contentToViewX(mNodeBounds.left); int right = mWebView.contentToViewX(mNodeBounds.right); int width = right - left; mPopup.setWidth(width); int bottom = mWebView.contentToViewY(mNodeBounds.bottom); int top = mWebView.contentToViewY(mNodeBounds.top); int height = bottom - top; AbsoluteLayout.LayoutParams lp = (AbsoluteLayout.LayoutParams) mAnchor.getLayoutParams(); boolean needsUpdate = false; if (null == lp) { lp = new AbsoluteLayout.LayoutParams(width, height, left, top); } else { if ((lp.x != left) || (lp.y != top) || (lp.width != width) || (lp.height != height)) { needsUpdate = true; lp.x = left; lp.y = top; lp.width = width; lp.height = height; } } Log.v("AutoCompletePopup", "resetRect layout " + lp.x + ", " + lp.y + ", " + lp.width + ", " + lp.height); if (needsUpdate) { mAnchor.setLayoutParams(lp); } if (mPopup.isShowing()) { Log.v("AutoCompletePopup", "showing popup again"); mPopup.show(); // update its position } } public void scrollDelta(int layerId, int dx, int dy) { if (layerId == mNodeLayerId) { mNodeBounds.offset(dx, dy); resetRect(); } } // AdapterView.OnItemClickListener implementation @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { if (id == 0 && position == 0 && mInputConnection.getIsAutoFillable()) { mText = ""; pushTextToInputConnection(); // Blank out the text box while we wait for WebCore to fill the form. if (mIsAutoFillProfileSet) { // Call a webview method to tell WebCore to autofill the form. mWebView.autoFillForm(mQueryId); } else { // There is no autofill profile setup yet and the user has // elected to try and set one up. Call through to the // embedder to action that. mWebView.getWebChromeClient().setupAutoFill( mHandler.obtainMessage(AUTOFILL_FORM)); } } else { Object selectedItem; if (position < 0) { selectedItem = mPopup.getSelectedItem(); } else { selectedItem = mAdapter.getItem(position); } if (selectedItem != null) { setText(mFilter.convertResultToString(selectedItem)); pushTextToInputConnection(); } } Log.v("AutoCompletePopup", "dismiss popup 5"); mPopup.dismiss(); } public void setIsAutoFillProfileSet(boolean isAutoFillProfileSet) { mIsAutoFillProfileSet = isAutoFillProfileSet; } private void pushTextToInputConnection() { Editable oldText = mInputConnection.getEditable(); mInputConnection.setSelection(0, oldText.length()); mInputConnection.replaceSelection(mText); mInputConnection.setSelection(mText.length(), mText.length()); } @Override public void onFilterComplete(int count) { if (!mIsFocused) { Log.v("AutoCompletePopup", "dismiss popup 1"); mPopup.dismiss(); return; } boolean showDropDown = (count > 0) && (mInputConnection.getIsAutoFillable() || mText.length() > 0); if (showDropDown) { if (!mPopup.isShowing()) { // Make sure the list does not obscure the IME when shown for the first time. mPopup.setInputMethodMode(ListPopupWindow.INPUT_METHOD_NEEDED); } Log.v("AutoCompletePopup", "showing popup"); mPopup.show(); mPopup.getListView().setOverScrollMode(View.OVER_SCROLL_ALWAYS); } else { Log.v("AutoCompletePopup", "dismiss popup"); mPopup.dismiss(); } } }
core/java/android/webkit/WebViewClassic.java +188 −8 Original line number Original line Diff line number Diff line Loading @@ -375,7 +375,7 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc * InputConnection used for ContentEditable. This captures changes * InputConnection used for ContentEditable. This captures changes * to the text and sends them either as key strokes or text changes. * to the text and sends them either as key strokes or text changes. */ */ private class WebViewInputConnection extends BaseInputConnection { class WebViewInputConnection extends BaseInputConnection { // Used for mapping characters to keys typed. // Used for mapping characters to keys typed. private KeyCharacterMap mKeyCharacterMap; private KeyCharacterMap mKeyCharacterMap; private boolean mIsKeySentByMe; private boolean mIsKeySentByMe; Loading @@ -383,11 +383,31 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc private int mImeOptions; private int mImeOptions; private String mHint; private String mHint; private int mMaxLength; private int mMaxLength; private boolean mIsAutoFillable; private boolean mIsAutoCompleteEnabled; private String mName; public WebViewInputConnection() { public WebViewInputConnection() { super(mWebView, true); super(mWebView, true); } } public void setAutoFillable(int queryId) { mIsAutoFillable = getSettings().getAutoFillEnabled() && (queryId != WebTextView.FORM_NOT_AUTOFILLABLE); int variation = mInputType & EditorInfo.TYPE_MASK_VARIATION; if (variation != EditorInfo.TYPE_TEXT_VARIATION_WEB_PASSWORD && (mIsAutoFillable || mIsAutoCompleteEnabled)) { if (mName != null && mName.length() > 0) { requestFormData(mName, mFieldPointer, mIsAutoFillable, mIsAutoCompleteEnabled); } } } public boolean getIsAutoFillable() { return mIsAutoFillable; } @Override @Override public boolean sendKeyEvent(KeyEvent event) { public boolean sendKeyEvent(KeyEvent event) { // Some IMEs send key events directly using sendKeyEvents. // Some IMEs send key events directly using sendKeyEvents. Loading Loading @@ -582,6 +602,9 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc mInputType = inputType; mInputType = inputType; mImeOptions = imeOptions; mImeOptions = imeOptions; mMaxLength = initData.mMaxLength; mMaxLength = initData.mMaxLength; mIsAutoCompleteEnabled = initData.mIsAutoCompleteEnabled; mName = initData.mName; mAutoCompletePopup.clearAdapter(); } } public void setupEditorInfo(EditorInfo outAttrs) { public void setupEditorInfo(EditorInfo outAttrs) { Loading Loading @@ -629,6 +652,13 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc REPLACE_TEXT, start, end, text.toString()); REPLACE_TEXT, start, end, text.toString()); mPrivateHandler.sendMessage(replaceMessage); mPrivateHandler.sendMessage(replaceMessage); } } if (mAutoCompletePopup != null) { StringBuilder newText = new StringBuilder(); newText.append(editable.subSequence(0, start)); newText.append(text); newText.append(editable.subSequence(end, editable.length())); mAutoCompletePopup.setText(newText.toString()); } mIsKeySentByMe = false; mIsKeySentByMe = false; } } Loading Loading @@ -795,6 +825,7 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc WebViewInputConnection mInputConnection = null; WebViewInputConnection mInputConnection = null; private int mFieldPointer; private int mFieldPointer; private PastePopupWindow mPasteWindow; private PastePopupWindow mPasteWindow; AutoCompletePopup mAutoCompletePopup; private static class OnTrimMemoryListener implements ComponentCallbacks2 { private static class OnTrimMemoryListener implements ComponentCallbacks2 { private static OnTrimMemoryListener sInstance = null; private static OnTrimMemoryListener sInstance = null; Loading Loading @@ -1104,6 +1135,7 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc private static final int SWITCH_TO_SHORTPRESS = 3; private static final int SWITCH_TO_SHORTPRESS = 3; private static final int SWITCH_TO_LONGPRESS = 4; private static final int SWITCH_TO_LONGPRESS = 4; private static final int RELEASE_SINGLE_TAP = 5; private static final int RELEASE_SINGLE_TAP = 5; private static final int REQUEST_FORM_DATA = 6; private static final int DRAG_HELD_MOTIONLESS = 8; private static final int DRAG_HELD_MOTIONLESS = 8; private static final int AWAKEN_SCROLL_BARS = 9; private static final int AWAKEN_SCROLL_BARS = 9; private static final int PREVENT_DEFAULT_TIMEOUT = 10; private static final int PREVENT_DEFAULT_TIMEOUT = 10; Loading Loading @@ -1156,6 +1188,9 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc static final int REPLACE_TEXT = 143; static final int REPLACE_TEXT = 143; static final int CLEAR_CARET_HANDLE = 144; static final int CLEAR_CARET_HANDLE = 144; static final int KEY_PRESS = 145; static final int KEY_PRESS = 145; static final int RELOCATE_AUTO_COMPLETE_POPUP = 146; static final int FOCUS_NODE_CHANGED = 147; static final int AUTOFILL_FORM = 148; private static final int FIRST_PACKAGE_MSG_ID = SCROLL_TO_MSG_ID; private static final int FIRST_PACKAGE_MSG_ID = SCROLL_TO_MSG_ID; private static final int LAST_PACKAGE_MSG_ID = HIT_TEST_RESULT; private static final int LAST_PACKAGE_MSG_ID = HIT_TEST_RESULT; Loading Loading @@ -3560,7 +3595,9 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc @Override @Override public void clearFormData() { public void clearFormData() { checkThread(); checkThread(); // TODO: Implement b/6083041 if (mAutoCompletePopup != null) { mAutoCompletePopup.clearAdapter(); } } } /** /** Loading Loading @@ -3861,12 +3898,12 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc } } private void scrollLayerTo(int x, int y) { private void scrollLayerTo(int x, int y) { if (x == mScrollingLayerRect.left && y == mScrollingLayerRect.top) { int dx = mScrollingLayerRect.left - x; int dy = mScrollingLayerRect.top - y; if (dx == 0 && y == 0) { return; return; } } if (mSelectingText) { if (mSelectingText) { int dx = mScrollingLayerRect.left - x; int dy = mScrollingLayerRect.top - y; if (mSelectCursorBaseLayerId == mCurrentScrollingLayerId) { if (mSelectCursorBaseLayerId == mCurrentScrollingLayerId) { mSelectCursorBase.offset(dx, dy); mSelectCursorBase.offset(dx, dy); } } Loading @@ -3874,6 +3911,9 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc mSelectCursorExtent.offset(dx, dy); mSelectCursorExtent.offset(dx, dy); } } } } if (mAutoCompletePopup != null) { mAutoCompletePopup.scrollDelta(mCurrentScrollingLayerId, dx, dy); } nativeScrollLayer(mCurrentScrollingLayerId, x, y); nativeScrollLayer(mCurrentScrollingLayerId, x, y); mScrollingLayerRect.left = x; mScrollingLayerRect.left = x; mScrollingLayerRect.top = y; mScrollingLayerRect.top = y; Loading Loading @@ -4726,6 +4766,7 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc } } private void onZoomAnimationEnd() { private void onZoomAnimationEnd() { mPrivateHandler.sendEmptyMessage(RELOCATE_AUTO_COMPLETE_POPUP); } } void onFixedLengthZoomAnimationStart() { void onFixedLengthZoomAnimationStart() { Loading Loading @@ -4880,11 +4921,20 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc public InputConnection onCreateInputConnection(EditorInfo outAttrs) { public InputConnection onCreateInputConnection(EditorInfo outAttrs) { if (mInputConnection == null) { if (mInputConnection == null) { mInputConnection = new WebViewInputConnection(); mInputConnection = new WebViewInputConnection(); mAutoCompletePopup = new AutoCompletePopup(mContext, this, mInputConnection); } } mInputConnection.setupEditorInfo(outAttrs); mInputConnection.setupEditorInfo(outAttrs); return mInputConnection; return mInputConnection; } } private void relocateAutoCompletePopup() { if (mAutoCompletePopup != null) { mAutoCompletePopup.resetRect(); mAutoCompletePopup.setText(mInputConnection.getEditable()); } } /** /** * Called in response to a message from webkit telling us that the soft * Called in response to a message from webkit telling us that the soft * keyboard should be launched. * keyboard should be launched. Loading Loading @@ -4915,6 +4965,91 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc } } } } /** * Called by AutoCompletePopup to find saved form data associated with the * textfield * @param name Name of the textfield. * @param nodePointer Pointer to the node of the textfield, so it can be * compared to the currently focused textfield when the data is * retrieved. * @param autoFillable true if WebKit has determined this field is part of * a form that can be auto filled. * @param autoComplete true if the attribute "autocomplete" is set to true * on the textfield. */ /* package */ void requestFormData(String name, int nodePointer, boolean autoFillable, boolean autoComplete) { if (mWebViewCore.getSettings().getSaveFormData()) { Message update = mPrivateHandler.obtainMessage(REQUEST_FORM_DATA); update.arg1 = nodePointer; RequestFormData updater = new RequestFormData(name, getUrl(), update, autoFillable, autoComplete); Thread t = new Thread(updater); t.start(); } } /* * This class requests an Adapter for the AutoCompletePopup which shows past * entries stored in the database. It is a Runnable so that it can be done * in its own thread, without slowing down the UI. */ private class RequestFormData implements Runnable { private String mName; private String mUrl; private Message mUpdateMessage; private boolean mAutoFillable; private boolean mAutoComplete; private WebSettingsClassic mWebSettings; public RequestFormData(String name, String url, Message msg, boolean autoFillable, boolean autoComplete) { mName = name; mUrl = WebTextView.urlForAutoCompleteData(url); mUpdateMessage = msg; mAutoFillable = autoFillable; mAutoComplete = autoComplete; mWebSettings = getSettings(); } @Override public void run() { ArrayList<String> pastEntries = new ArrayList<String>(); if (mAutoFillable) { // Note that code inside the adapter click handler in AutoCompletePopup depends // on the AutoFill item being at the top of the drop down list. If you change // the order, make sure to do it there too! if (mWebSettings != null && mWebSettings.getAutoFillProfile() != null) { pastEntries.add(mWebView.getResources().getText( com.android.internal.R.string.autofill_this_form).toString() + " " + mAutoFillData.getPreviewString()); mAutoCompletePopup.setIsAutoFillProfileSet(true); } else { // There is no autofill profile set up yet, so add an option that // will invite the user to set their profile up. pastEntries.add(mWebView.getResources().getText( com.android.internal.R.string.setup_autofill).toString()); mAutoCompletePopup.setIsAutoFillProfileSet(false); } } if (mAutoComplete) { pastEntries.addAll(mDatabase.getFormData(mUrl, mName)); } if (pastEntries.size() > 0) { ArrayAdapter<String> adapter = new ArrayAdapter<String>( mContext, com.android.internal.R.layout.web_text_view_dropdown, pastEntries); mUpdateMessage.obj = adapter; mUpdateMessage.sendToTarget(); } } } /** /** * Dump the display tree to "/sdcard/displayTree.txt" * Dump the display tree to "/sdcard/displayTree.txt" * * Loading Loading @@ -4990,6 +5125,13 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc || keyCode == KeyEvent.KEYCODE_NUMPAD_ENTER; || keyCode == KeyEvent.KEYCODE_NUMPAD_ENTER; } } public boolean onKeyPreIme(int keyCode, KeyEvent event) { if (mAutoCompletePopup != null) { return mAutoCompletePopup.onKeyPreIme(keyCode, event); } return false; } @Override @Override public boolean onKeyDown(int keyCode, KeyEvent event) { public boolean onKeyDown(int keyCode, KeyEvent event) { if (DebugFlags.WEB_VIEW) { if (DebugFlags.WEB_VIEW) { Loading Loading @@ -5593,6 +5735,7 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc // However, do not update the base layer as that hasn't changed // However, do not update the base layer as that hasn't changed setNewPicture(mLoadedPicture, false); setNewPicture(mLoadedPicture, false); } } relocateAutoCompletePopup(); } } @Override @Override Loading Loading @@ -8020,6 +8163,12 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc } } break; break; } } case REQUEST_FORM_DATA: if (mFieldPointer == msg.arg1) { ArrayAdapter<String> adapter = (ArrayAdapter<String>)msg.obj; mAutoCompletePopup.setAdapter(adapter); } break; case LONG_PRESS_CENTER: case LONG_PRESS_CENTER: // as this is shared by keydown and trackballdown, reset all // as this is shared by keydown and trackballdown, reset all Loading Loading @@ -8174,6 +8323,11 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc } } break; break; case FOCUS_NODE_CHANGED: if (mAutoCompletePopup != null) { mAutoCompletePopup.setFocused(msg.arg1 == mFieldPointer); } // fall through to HIT_TEST_RESULT case HIT_TEST_RESULT: case HIT_TEST_RESULT: WebKitHitTest hit = (WebKitHitTest) msg.obj; WebKitHitTest hit = (WebKitHitTest) msg.obj; mFocusedNode = hit; mFocusedNode = hit; Loading @@ -8190,11 +8344,20 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc case SET_AUTOFILLABLE: case SET_AUTOFILLABLE: mAutoFillData = (WebViewCore.AutoFillData) msg.obj; mAutoFillData = (WebViewCore.AutoFillData) msg.obj; // TODO: Support (b/6083041) if (mInputConnection != null) { mInputConnection.setAutoFillable(mAutoFillData.getQueryId()); mAutoCompletePopup.setAutoFillQueryId(mAutoFillData.getQueryId()); } break; break; case AUTOFILL_COMPLETE: case AUTOFILL_COMPLETE: // TODO: Support (b/6083041) if (mAutoCompletePopup != null) { ArrayList<String> pastEntries = new ArrayList<String>(); mAutoCompletePopup.setAdapter(new ArrayAdapter<String>( mContext, com.android.internal.R.layout.web_text_view_dropdown, pastEntries)); } break; break; case COPY_TO_CLIPBOARD: case COPY_TO_CLIPBOARD: Loading @@ -8208,6 +8371,11 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc mFieldPointer = initData.mFieldPointer; mFieldPointer = initData.mFieldPointer; mInputConnection.initEditorInfo(initData); mInputConnection.initEditorInfo(initData); mInputConnection.setTextAndKeepSelection(initData.mText); mInputConnection.setTextAndKeepSelection(initData.mText); nativeMapLayerRect(mNativeClass, initData.mNodeLayerId, initData.mNodeBounds); mAutoCompletePopup.setNodeBounds(initData.mNodeBounds, initData.mNodeLayerId); mAutoCompletePopup.setText(mInputConnection.getEditable()); } } break; break; Loading Loading @@ -8236,6 +8404,15 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc mWebViewCore.sendMessage(EventHub.KEY_PRESS, msg.arg1); mWebViewCore.sendMessage(EventHub.KEY_PRESS, msg.arg1); break; break; case RELOCATE_AUTO_COMPLETE_POPUP: relocateAutoCompletePopup(); break; case AUTOFILL_FORM: mWebViewCore.sendMessage(EventHub.AUTOFILL_FORM, msg.arg1, /* unused */0); break; default: default: super.handleMessage(msg); super.handleMessage(msg); break; break; Loading Loading @@ -9019,7 +9196,8 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc } } /*package*/ void autoFillForm(int autoFillQueryId) { /*package*/ void autoFillForm(int autoFillQueryId) { mWebViewCore.sendMessage(EventHub.AUTOFILL_FORM, autoFillQueryId, /* unused */0); mPrivateHandler.obtainMessage(AUTOFILL_FORM, autoFillQueryId, 0) .sendToTarget(); } } /* package */ ViewManager getViewManager() { /* package */ ViewManager getViewManager() { Loading Loading @@ -9169,4 +9347,6 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc private static native int nativeGetHandleLayerId(int instance, int handle, private static native int nativeGetHandleLayerId(int instance, int handle, Rect cursorLocation); Rect cursorLocation); private static native boolean nativeIsBaseFirst(int instance); private static native boolean nativeIsBaseFirst(int instance); private static native void nativeMapLayerRect(int instance, int layerId, Rect rect); } }
core/java/android/webkit/WebViewCore.java +20 −8 File changed.Preview size limit exceeded, changes collapsed. Show changes